【C进阶】内功修炼秘籍|【C进阶】two -> 指针进阶

※※※大家好!我是同学〖森〗,一名计算机爱好者,今天让我们进入学习模式。若有错误,请多多指教。 点赞 ? 收藏 留言 都是我创作的最大的动力!
目录
1、 字符指针
2、指针数组
3、数组指针
3.1数组指针的定义
指针数组 VS 数组指针
3.2、&数组名VS数组名
3.3 数组指针的使用


指针概念
1.指针( 指针变量 )就是个变量,用来存放地址( 内存在计算中的编号 ),地址唯一标识一块内存空间。2.指针的大小是固定的4( 32位平台 )/8( 64位平台 )个字节 。3.指针是有类型,指针的类型决定了指针的 + - 整数的步长,指针解引用操作的时候的权限。4.指针的运算。( 指针+整数、指针-指针、指针的关系运算 )
1、 字符指针 使用1.
#include int main() { char a = 'w'; char* p = &a; *p = 's'; printf("%c", *p); return 0; }

使用2.
#include int main() { const char* p = "I love China"; printf("%c\n", *p); printf("%s\n", p); return 0; }

P说:“我是字符指针变量,我存储这I的地址,不是字符串“I love China”喔!”
字符串说:“对啊对啊!我太大了,而P哥哥只有4个byte。放不下我!只有老大'I' 的电话号码(地址)在p哥哥中。有事可以打电话呦。”
字符串:“再多说一句,我是常量字符串,我的家在常量区,我这的地方的房价是无价的哦!不能移民(不能修改)欢迎你来找我玩!大家交个朋友吧!”
p1:“屏幕前的你,我们一起来玩个游戏吧!猜猜我会输出什么”
#include int main() { const char* p1 = "abcdef"; const char* p2 = "abcdef"; char arr1[] = "abcdef"; char arr2[] = "abcdef"; if (p1 == p2) { printf("p1 == p2\n"); } else { printf("p1 != p2\n"); } if (arr1 == arr2) { printf("arr1 == arr2\n"); } else { printf("arr1 != arr2\n"); } return 0; }

p1问p2:"p2,为什么你的内容和我的一样,你认识的是常量区的常量字符串吗?"
p2:“是的呀,它可是我最好的好朋友呀!怎么你也认识它?”
p1:“这么巧,它也是我的好朋友,0x00097B30这是他的电话号。俗话说:“朋友的朋友就是我的朋友,那我们也是好朋友了。””
p2:“我也有它的电话号。它的电话号和你的一样,看来我们认识的是一个人;”
就这样,p1,p2成为了好朋友。
有一天arr1看见arr2手里拿的它兄弟“abcdef” 的名字。就问arr2:
“你认识abcdef吗?它可是我的铁哥们?”
arr2回答道:“我当然认识,我还有它的电话号呢!0x0095f7f8 ”
arr1:“不对啊!肯定是你记错了,它的电话号是0x0095f808.”
arr2:“你记错了,我怎么聪明怎么能记错呢!”
arr1:“那就是你说我比你笨喽!有本事打一架。”
arr2:“来就来!谁怕谁”
就怎样arr1和arr2成为了愁人。
【C进阶】内功修炼秘籍|【C进阶】two -> 指针进阶
文章图片

p2:“聪明的你猜对了吗? ”

2、指针数组
整型数组:int arr【10】存放整型的数组
字符数组:int arr【10】存放字符的数组
指针数组:int * arr【10】存放指针的数组
#include int main() { int arr1[5] = { 1,2,3,4,5 }; int arr2[5] = { 6, 7, 8, 9, 10 }; int arr3[5] = { 11, 12, 13, 14, 15 }; int* p[3] = { arr1, arr2, arr3 }; //整型指针数组 for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { //printf("%d ", p[i][j]); //方式一 printf("%d ", *(p[i] + j)); //方式二 }printf("\n"); } return 0; }

【C进阶】内功修炼秘籍|【C进阶】two -> 指针进阶
文章图片

3、数组指针 3.1数组指针的定义
数组指针是指针?还是数组?答案是: 指针。
大家都知道:
整型指针:
int a = 5; int* pa = &a;pa为整型指针,指向整型的指针,存放整型变量的地址。
字符指针:
char b = 'b'; char * pb = &b; pb为字符指针,指向字符的指针,存放字符变量的地址。
数组指针:->指向数组的指针,存放数组的地址。

指针数组 VS 数组指针
int * p1 [10];
int (* p2) [10];
【【C进阶】内功修炼秘籍|【C进阶】two -> 指针进阶】p1先和【10】结合,p1相当于数组名,包含10各元素,每个元素都存的是地址。p1是指针数组
p2先和*结合,p2相当于指针变量,指着指向的是一个大小为10个整型的数组。所以p2是一个指针,指向一个数组,叫做数组指针。
3.2、&数组名VS数组名 【C进阶】内功修炼秘籍|【C进阶】two -> 指针进阶
文章图片

根据上面的代码我们发现,其实&a和a,虽然值是一样的,但是意义应该不一样的。但a与&a【0】的意义是一样的。 实际上:&a 表示的是数组的地址,而不是数组首元素的地址。 (细细体会一下)本例中&a的类型是:int(*)[10] ,是一种数组指针类型数组的地址 +1 ,跳过整个数组的大小,所以&arr+1相对于&arr的差值是 40.0113FDD0
0113FDF8而这两个地址正好相差40.
屏幕前聪明的你,我们来回答个小问题:、
int* arr【10】;
&arr;放在什么变量里。
int * (*p)【10】 = &arr;把名字去掉就是它的类型。p的类型是int *(*)【】;
那么我们怎么来理解数组名呢?
通常情况下,我们说的数组名都是数组首元素的地址。
但有两个例外:
1、sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小。
2、&数组名,这里的数组名表示整个数组,&数组名,取出的是整个数组的地址

3.3 数组指针的使用 既然我们学了数组指针,那么数组指针有什么用呢?让我们一探究竟。
用函数打印一维数组。
#include//形参写成数组形式void print(int p[], int n) { int i = 0; for (i = 0; i < n; i++) { printf("%d ", p[i]); } printf("\n"); }//形参写成指针数组形式 void print2(int* p, int n) { int i = 0; for (i = 0; i < n; i++) { printf("%d ", p + i); } printf("\n"); }//形参写成指针数组形式void print3(int (*p) [10], int n) //*p必须加括号,[10]不能省略。且[]的数字必须和传入的数组元素相同 { int i = 0; for (i = 0; i < n; i++) { //*p相当于arr数组名,数组名是首元素的地址。所以*p相当于&arr[0] printf("%d ", *(*p + i)); } printf("\n"); }int main() { int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int ch = sizeof(arr) / sizeof(arr[0]); print(arr, ch); print(arr, ch); //传递的是数组首元素的地址。 print(&arr, ch); //传递的是数组的地址。 return 0; }

从上述代码看,如果实参传递的是数组首元素的地址,我们可以用一维数组和整型指针接收。但如果实参传递的是数组的地址。就必须用数组指针来接收了。因过于麻烦。不建议使用。传数组地址的方法打印。如果就是为了耍酷,就请自便。
一维数组会了,那我们来研究下二维数组的打印。
#include//形参为二维数组。 void print(int a[3][4], int n, int m) { int i = 0, j = 0; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) printf("%2d ", a[i][j]); printf("\n"); } }//形参为数组指针//*p代表p为指针变量,【4】代表数组指针指向的数组一行有4个变量。 //int代表p指针指向的数组的元素的类型为int形。p的类型为 int (*)[4]. void print1(int (*p)[4], int n, int m) { int i = 0, j = 0; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) //printf("%2d ", p[i][j]); //p+i代表第i行,再解引用代表第i行的第一个元素的地址,再加j代表第i行第j列的地址。最后再解引用。 printf("%2d ", *(*(p + i) + j)); printf("\n"); } }int main() { int s[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; print(s, 3, 4); print1(s, 3, 4); //传递的是行地址,相当于第一行的地址。 return 0; }

聪明的你学会了吗?有什么疑问,见解,在文章下面留下你的痕迹吧!

    推荐阅读