『C语言初阶』第七章 -初识指针

这篇具有很好参考价值的文章主要介绍了『C语言初阶』第七章 -初识指针。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

『C语言初阶』第七章 -初识指针,C语言初阶知识,c语言,c++

🔥博客主页 小羊失眠啦.
🔖系列专栏 C语言
🌥️每日语录苦难是化了妆的祝福。
❤️感谢大家点赞👍收藏⭐评论✍️


『C语言初阶』第七章 -初识指针,C语言初阶知识,c语言,c++

前言

时隔多日小羊又来给铁汁们更新C语言之初识指针,指针是C语言中一个关键且强大的概念,理解和掌握指针对于编写高效、灵活的程序至关重要。本文将详细解释C语言中的指针,帮助初学者迈出掌握编程世界的第一步。


一、指针是什么?

  1. 指针是内存中一个最小单元的编号,也就是地址
  2. 一般我们所说的指针,通常是指指针变量,用来存放内存地址的变量

1.内存

程序在运行时候会在内存中被调用,运行时占用内存的空间。
内存就像一栋楼,里面有很多房间,每一户人家(每一块内存)都有一个门牌号,而这个门牌号就相当于内存编号,我们就可以通过编号找到相对应的内存(值)。
编号也被称为地址,不同内存块所对应的地址也不一样。

2.指针变量

指针变量也是一种变量,只不过是用来存储地址的变量
我们可以通过&(取地址操作符)取出变量的内存起始地址,把该地址存放到一个变量中,这个变量就是指针变量

#include<stdio.h>
int main()
{
	int a = 5;
	int* p = &a;//取出a的地址存放到变量p中
	printf("%p\n", &a);
	printf("%p", p);
	return 0;
}

『C语言初阶』第七章 -初识指针,C语言初阶知识,c语言,c++

总结:指针是一个变量,但它存储的是另一个变量的内存地址,而不是直接存储数据本身。可以将指针看作是数据的"门牌号码",通过它可以找到内存中存储的实际数据。

3.指针大小

在32位电脑上,地址是32个0或者1组成二进制序列,那地址就是32b(位)=4B(字节)的空间来存储,所以一个指针变量的大小就是4个字节。
相应的在64位机器上,64b=8B,一个指针变量大小就是8个字节。

总结:
1. 指针是用来存放地址的,地址是唯一标识一块内存单元的。
2. 指针大小在32位平台上是4个字节,在64位平台是8个字节。


二、指针类型

指针变量是变量,变量有很多类型,那指针变量的类型也是如此。
当我们需要指向不同类型的变量时,就需要创建不同类型的指针变量。

	char* p1 = NULL;//创建一个char类型的指针,并初始化为空指针
	int* p2 = NULL;//创建一个int类型的指针,并初始化为空指针
	short* p3 = NULL;
	long* p4 = NULL;
	float* p5 = NULL;
	double* p6 = NULL;

所以指针的定义方式为:类型 + * = 值。

解读:

  1. char*类型指针是为了存放char类型变量的地址
  2. int*类型指针是为了存放int类型变量的地址
  3. double*类型指针是为了存放double类型变量的地址

注意:
指针大小与指针类型无关,指针大小与计算机(32位或者64位有关)

1.指针类型的作用

从上面代码可知,不同类型指针大小相同,那么指针类型的意义是什么呢?

用法示例

#include <stdio.h>
int main()
{
	int n = 10;
	char* p1 = (char*)&n;//将int类型地址强制转化为char类型
	int* p2 = &n;
 
	printf("%p\n", &n);
	printf("%p\n", p1);
	printf("%p\n", p1 + 1);
	printf("%p\n", p2);
	printf("%p\n", p2 + 1);
	return  0;
}

『C语言初阶』第七章 -初识指针,C语言初阶知识,c语言,c++

我们发现:
当指针为char类型时,指针+1,步长为1
当指针为int
类型时,指针+1,步长为4

总结:不同类型的指针变量决定了指针向前或向后走一步有多大(距离),即步长。

2.指针的解引用

我们知道,指针保存内存的地址,那指针的作用是什么呢?
我们可以通过指针保存的地址,来访问内存中的目标变量,并将其修改,这就需要使用指针的解引用操作

用法示例

#include <stdio.h>
int main()
{
	int n = 0x11223344;
	char* p1 = (char*)&n;
	int* p2 = &n;
	*p1 = 0;   
	*p2 = 0;   
	printf("%#x\n", n);
	printf("%#x\n", p1);
	return 0;
}

『C语言初阶』第七章 -初识指针,C语言初阶知识,c语言,c++

分析:
因为p2是int类型指针变量,所以能访问四个字节的空间,*p2=0,将n的值修改为0;
但是p1是char类型指针变量,所以只能访问一个字节的空间,那为何又是修改地址中的44而不是11呢,后面文章会详解大小端的知识。

总结:

  1. 指针的类型决定指针加减整数时所跳过的步长
  2. 指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)

三、野指针

概念:野指针就是指针的位置是不可知的(随机的、不正确的、没有正确限制的)指针。
野指针很危险,它访问的空间不可知,从而导致出现的可能情况有:

  1. 指针未初始化
  2. 指针越界或者非法访问
  3. 指针指向的空间被释放了(例:局部变量)

用法示例

#include <stdio.h>
int main()
{
	//1>:
	int* p1;
	*p1 = 5;
	//此时p1就是一个野指针。

	//2>:
	int arr[10] = { 0 };
	int i = 0;
	int* p2 = arr;//p指向数组的首地址
	for (i = 0; i < 11; i++)
	{
		*(p2++)=i;
	}
	//当p2指向的空间超过数组的最后一个元素时,指针就非法访问,即越界访问了未知空间。
	//此时p2是野指针。

	//3>:
	int j = 0;
	for (j = 0; j < 5; j++)
	{
		int a = 5;
		a += 1;
	}
	int* p3 = &a;//当循环结束之后,局部变量a向内存申请的空间就被释放了。
	//此时p3指针指向的空间就是已经被释放掉的空间。p3就是野指针。

	return 0;
}

如何规避野指针

  • 指针初始化
  • 小心指针越界
  • 指针指向空间释放及时置NULL
  • 避免返回局部变量的地址
  • 指针使用之前检查有效性

四、指针的运算

1.指针加减整数

用法示例

例:打印一维数组

#include<stdio.h>
int main()
{
	int arr[5] = { 1,2,3,4,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	int* p = arr;
	for (i = 0; i < 5; i++)
		printf("%d ", *p + i);
	return 0;
}

2.指针-指针

指针减指针可以用来计算字符数组的长度或字符串的长度

用法示例

#include <stdio.h>
int my_strlen(char* s)
{
	char* p = s;
	while (*p != '\0')
		p++;
	return p - s;
}
int main()
{
	char str[] = "hello world";
	int len = my_strlen(str);
	printf("%d", len);
	return 0;
}

3.指针的关系运算

标准规定:
允许指向数组元素的指针与指针数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。


五、二级指针

指针变量也是变量,变量有地址,那么指针变量的地址存放在哪里?
这时候就来了解二级指针!

#include <stdio.h>
int main()
{
	int a = 10;
	int* p1 = &a;
	int** p2 = &p1;//p2就是二级指针,指向p1
	**p2 = 6;
	printf("%d", a);
	return 0;
}

『C语言初阶』第七章 -初识指针,C语言初阶知识,c语言,c++
a的地址存放在p1中,p1的地址存放在p2中
p1是一级指针,而p2是二级指针
**p2=6通过第一次解引用找到p1,再第二次解引用找到a,将其修改为6

以此还有三级指针和其他多级指针,常见的就是一级和二级指针


指针的注意事项

  • 指针操作前应该初始化,避免出现未定义行为。
  • 指针可以进行比较操作,但仅在指向同一数组中的元素时才有意义。
  • 避免野指针(指向未知内存区域的指针)的使用,这可能导致程序崩溃。

结论:

初学者理解指针是学习C语言的重要一步,它使得程序可以更加灵活和高效地操作内存。通过掌握指针的基本概念、操作和用途,可以构建出更加复杂和强大的C语言程序。逐步练习并在实际项目中应用指针,将有助于加深对指针的理解和熟练掌握。


『C语言初阶』第七章 -初识指针,C语言初阶知识,c语言,c++
小羊希望本文对初学者理解C语言中的指针概念提供了一些帮助。在进一步学习过程中,还请查阅相关文档和示例以加深理解,咱们下期再见~~文章来源地址https://www.toymoban.com/news/detail-639536.html

到了这里,关于『C语言初阶』第七章 -初识指针的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构第七章

    图(Graph)G由两个集合V和E组成,记为G=(V, E),其中V是顶点的有穷非空集合,E是V中顶点偶对的有穷集合,这些顶点偶对称为边。V(G)和E(G)通常分别表示图G的顶点集合和边集合,E(G)可以为空集。若EG)为空,则图G只有顶点而没有边。 子图:假设有两个图G=(V,E)和G1=(V1,E1);如果V1

    2024年02月03日
    浏览(66)
  • 第七章 测试

    7.1.1 选择程序设计语言 1. 计算机程序设计语言基本上可以分为汇编语言和高级语言 2. 从应用特点看,高级语言可分为基础语言、结构化语言、专用语言 01 有理想的模块化机制; 02 可读性好的控制结构和数据结构; 03 便于调试和提高软件可靠性; 04 编译程序发现程序错误的

    2024年02月08日
    浏览(80)
  • python第七章(字典)

    一。字典(类型为dict)的特点: 1.符号为大括号 2.数据为键值对形式出现 3.各个键值对之间以逗号隔开 格式:str1={\\\'name\\\':\\\'Tom\\\'}  name相当于键值(key),Tom相当于值 二。空字典的创建方法 三。字典的基本操作(增删改查) 1.字典的增加操作:字典序列[key] = 值 注意点:如果存

    2024年01月24日
    浏览(58)
  • 第七章金融中介

             金融中介是通过向资金盈余者发行 间接融资合约( 如存款单),并和资金短缺者达成 间接投资合约 (发放信贷)或购买其发行的证券,在资金供求方之间融通资金,对资金跨期、跨域进行优化配置的金融机构。         金融体系由金融市场和金融中介构成,以银行业为

    2024年02月04日
    浏览(59)
  • 第七章 函数矩阵

    和矩阵函数不同的是,函数矩阵本质上是一个矩阵,是以函数作为元素的矩阵。 矩阵函数本质上是一个矩阵,是以矩阵作为自变量的函数。 函数矩阵和数字矩阵的运算法则完全相同。 不过矩阵的元素 a i j ( x ) a_{ij}(x) a ij ​ ( x ) 需要是闭区间 [ a , b ] [a,b] [ a , b ] 上的实函数

    2024年02月04日
    浏览(63)
  • [JavaScript] 第七章 对象

    🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 [Java项目实战] 介绍Java组件安装、使用;手写框架等 [Aws服务器实战] Aws Linux服务器上操作nginx、git、JDK、Vue等 [Java微服务

    2024年02月02日
    浏览(132)
  • 第七章 图论

    第七章 图论 一、数据结构定义 图的邻接矩阵存储法 图的邻接表存储法 把所有节点存储为节点数组,每个节点里有自己的数据和一个边指针,这个边指针相当于一个链表的头指针,这个链表里存放所有与这个节点相连的边,边里存放该边指向的节点编号和下一条边指针 图的

    2024年02月14日
    浏览(96)
  • OpenCV:第七章、图像变换

    目录 第七章:图像变换 7.1、基于OpenCV的边缘检测 7.1.1、一般步骤 1、滤波 2、增强 3、检测 7.1.2、canny算子 1、canny算子简介 2、canny边缘检测的步骤 7.2、霍夫变换  7.2.2、OpenCV中的霍夫线变换 7.2.3、霍夫线变换原理        7.2.4、标准霍夫变换:HoughLines()函数    7.2.5、累计概率

    2024年02月03日
    浏览(72)
  • 第七章 正则表达式

    目录 1.1. 概念: 1.2. 基本正则表达式 1.2.1. 常见元字符 1.2.2. POSIX字符类 1.2.3. 示例 1.3. 扩展正则表达式 1.3.1. 概念 1.3.2. 示例 在进行程序设计的过程中,用户会不可避免地遇到处理某些文本的情况。有的时候,用户还需要查找符合某些比较复杂规则的字符串。对于这些情况,如

    2024年03月17日
    浏览(87)
  • 第七章 高级 OOP 特性

    7.3.3 继承与延迟静态绑定 在创建类层次结构时,有时候回遇到这种情况,即父类方法要使用静态类属性,但静态类属性可能在子类中被覆盖。这和 self 的使用有关。我们看一个例子,其中 Employee 类和 Executive 类都做了一些修改: 执行代码如下: Watching Football  因为

    2024年02月11日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包