【C语言】初阶指针的简单使用 _指针运算 指针和数组的关系[初阶篇 _学习专用]
创始人
2024-04-11 07:07:51

1.指针是什么?

在学习指针的时候,我们经常会看到下面这段代码:

int main()
{int a = 10;int* pa = &a;*pa = 20;
}

之前并没有接触过指针的朋友们看到后可能是一头雾水,根本不知道从哪里去理解;下面我们就通过一些场景慢慢的去理解:

试想一下:如果你要给你的好朋友寄过去一些好吃的,然而你并不知道地址,这时你也许就会很懊恼;但如果你知道了你的好朋友的地址,你就可以通过快递把这些好吃的送到你朋友的身边。

把我们日常所说的地址类比到计算机,其实那些地址对应的就是计算机内存中的内存单元编号,也就是我们所说的指针。

比如说一栋宿舍楼,你在303号房间,你的朋友在605号房间,那么你就需要通过楼层和门牌号来找到你朋友所在的位置。

内存单元编号 = 地址 = 指针(指针变量,习惯于称为指针)。

指针就是存放地址的变量;下面通过一幅图来更好的理解上面的代码:

 * :解引用操作符,也叫间接访问操作符。

*pa就是找到0x0012ff40这片地址空间存储的数据,进而可以进行打印和修改。

这里还涉及到一个大小端存储的问题,我们所用到的vs2019是小端字节序存储(低位数据存储在低地址),把存储的地址倒着读取就是a的地址。 

指针的大小

int main()
{printf("%d\n", sizeof(int*));printf("%d\n", sizeof(char*));printf("%d\n", sizeof(long*));printf("%d\n", sizeof(long long*));printf("%d\n", sizeof(float*));printf("%d\n", sizeof(double*));return 0;
}

运行结果:

这里有很多人会有疑问:为什么结果是一样的,并且大小都是4?

那么接着往下看:

对于32位机器,假设有32根地址线,那么32根地址线产生的地址就会是:

1个字节 = 8个比特位;所以把这32个字节存储起来需要4个比特位;sizeof(指针变量)在32位机器下的结果就是4。

在64位机器下,地址是由64根地址线组成的,和32位机器下存储的道理是一样的——指针的大小是8个字节;

1.在32位机器下,指针的大小是一定的,都是4个字节。

2.在64位机器下,指针的大小也是一定的,都是8个字节。

2.指针和指针类型

指针也是变量,也是有类型的:

int a = 10;
int* pa = &a;//pa指向的空间时int类型,pa是一个整型指针
char ch = 'a';
char* pc = &ch;//pc指向的空间时char类型,pc是一个字符指针

2.1 解引用指针变量 

不同类型的指针变量解引用访问权限不同,光说不练假把式,下面通过两段程序来进一步了解:

程序1:

int main()
{int arr[10] = { 0 };char* pc = (char*)arr;for (int i = 0; i < 40; i++){*pc = 'x';pc++;}return 0;
}

  

程序2:

int main()
{int arr[10] = { 0 };int* pa = arr;for (int i = 0; i < 10; i++){*pa = 0x11223344;pa++;}return 0;
}

 

通过vs的调试窗口可以发现,int类型的指针解引用时可以访问四个字节,char类型的指针解引用时可以访问一个字节;

指针类型决定了解引用时的访问权限。

2.2 指针步长

不同的指针类型不仅解引用时访问权限有所不同,步长也是不同的:

int main()
{int a = 10;int* pa = &a;printf("%p\n", pa);printf("%p\n", pa + 1);char* pc = (char*)&a;printf("%p\n", pc);printf("%p\n", pc + 1);return 0;
}

 

指针的类型决定了指针向前或者向后一步所走的步长;

整型指针一步的步长为4个字节,字符型为1个字节。

3.野指针

野指针:指针指向的位置是不可知的随机的、不正确的、没有明确限制的)。

3.1 野指针成因

1.指针未初始化

int main()
{int* p;//局部变量指针未初始化,默认值为随机值*p = 20;return 0;
}

2.指针越界访问

int main()
{int arr[10] = { 0 };int* p = arr;for (int i = 0; i <= 11; i++){//当指针指向的范围超出数组arr的范围时,p就是野指针*(p++) = i;}return 0;
}

3.已经销毁的栈帧

int* test()
{int a = 10;return &a;
}
int main()
{int* pa = test();//出了test函数,栈帧销毁printf("%d\n", *pa);return 0;
}

3.2 如何避免野指针 

1.指针初始化

2.小心指针越界

3.指针指向空间释放即使置NULL

4.避免返回局部变量的地址

5.指针使用之前检查有效性

int main()
{int* p = NULL;int a = 10;p = &a;if (p != NULL){*p = 20;}return 0;
}

4.指针运算

4.1 指针+-整数

指针+整数:

int main()
{int arr[10] = { 0 };int* pa = arr;for (int i = 0; i < 10; i++){*(pa+i) = 10;//指针+整数}return 0;
}

指针-整数和指针+整数是相似的,这里就不过多解释了。 

4.2 指针-指针

指针减指针是有前提的,相减的两个指针必须是连续的,一般常用语数组。

int main()
{int arr[10] = { 0 };printf("%d\n", &arr[9] - &arr[0]);return 0;
}

指针-指针得到的是指针之间元素的个数; 

指针减指针实现库函数strlen:

int my_strlen(char* str)
{char* ch = str;while (*str != '\0'){str++;}return str - ch;
}
int main()
{char arr[] = "abcdef";int ret = my_strlen(arr);return 0;
}

5.指针和数组 

首先,我们来了解一个概念——数组名;

数组名:首元素地址;下面两种情况除外;

1.sizeof(arr),arr表示整个数组,sizeof(arr)求出的是整个数组的大小。

2.&arr,此时arr表示整个数组,&arr取出的是整个数组的地址。

 

&arr和arr打印出的地址是相同的,那我们怎么证明&arr取出的是整个数组的地址呢?

int main()
{int arr[10] = { 0 };printf("%p\n", &arr);printf("%p\n", &arr + 1);printf("%p\n", arr);printf("%p\n", arr + 1);return 0;
}

 

&arr+1所走的步长是40个字节,刚好是数组的大小,说明&arr取出的确实是整个数组的地址。 

6.二级指针

int main()
{int a = 10;int* pa = &a;int** ppa = &pa;return 0;
}

 

 

初阶指针的使用到这里就结束了,对以上内容存在疑问的可以直接私信博主,Fighting! Fighting! Fighting!

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...