> 文档中心 > 指针深度解刨《四》(指针和数组的 “亲密“ 关系)

指针深度解刨《四》(指针和数组的 “亲密“ 关系)

今天我们主要聊一下指针数组亲密关系,他们到底有什么相同和不同呢?

 

今天大家也要心情愉悦哦!

 

 

指针和数组有关系吗?

大家都知道数组和指针在访问方式上都很相似,那么他们之间有关系吗?且听我娓娓道来。

指针形式定义字符串并访问

首先我们用指针定义一个字符串,分别用两种方式访问(指针访问,和【】访问)

const char *p = "holle boy";int len = strlen(p);printf("指针形式访问\n");    for (int i = 0; i < len; i++){printf("%c ", *(p + i));}printf("\n数组形式访问\n");for (int i = 0; i < len; i++){printf("%c ", p[i]);}

 

可以看出p用哪一种访问方式都可以,那么这可以说明指针和数组有关系吗?(现在还不确定)

另外说下p,这个开辟的字符串是在内存中的字符常量区的,即使没有const 也不可以修改内部的值,因为这是在操作系统级别的保护。在main函数栈帧中存放的是指针变量p的地址,而p的指向是在字符常量区所创建的字符串的首地址处,简略图,供大家参考。

 

数组形式定义字符串并访问

那么数组形式定义一个字符串,并访问他。

    char q []= "holle girl";int len = strlen(q);printf("指针形式访问\n");for (int i = 0; i < len; i++){printf("%c ", *(q + i));}printf("\n数组形式访问\n");for (int i = 0; i < len; i++){printf("%c ", q[i]);}

 这是数组开辟的,并且用两种形式访问的。好像数组也可以用指针形式访问啊,那么指针和数组有关系吗?(还是不确定)

对比两者区别

先讲个小例子吧,假如这个世界上有你的双胞胎,它的身形外貌和你一样,甚至作息都和你一样,你兄弟是和你完全一样吗?

首先你们可能有很多相似的地方,甚至作息相同,但是在本质上,你们是完全不同的两种人格,所以是完全不等价的。

指针和数组这两个就像是双胞胎,他们很像,但是我们不能把它们在概念或者本质上混为一谈。

以上面的例子分析:

这个是数组的存放,是在栈区开辟的空间,所有的字符串的元素都在栈上,并且可以修改值。

都可以用指针和数组形式进行访问。

 

 

 这个是指针形式的存放开辟的空间,在栈区处存放的是p的地址,而在字符常量区存放的字符串的内容。并且值不可被修改。

这样分析,那么从字符串的存储角度,那么指针和数组是没有一点一点关系,只不过在访问方式上他们有很多相似之处

得出结论:指针和数组没有关系 

数组传参的降维问题

首先我们要知道数组在进行函数调用传参时,会发生降维,降为成指针。

看个例子:

void Show(int arr[] /*int* arr*/, int num){for (int i = 0; i < num; i++){printf("%d ", arr[i]);}printf("\n");}int main(){int a[5] = { 1, 2, 3, 4, 5 };int num = sizeof(a) / sizeof(a[0]);Show(a, num);return 0;}

首先,这是把数组元素打印在屏幕上,那么各位注意过没有函数的形参int arr[]和int *arr都可以打印出结果。为什么呢?并且为什么可以int *的指针接收呢?

通过调试可以看出结果:

 可以看出arr的类型是int*的表示arr传的是首元素地址,用int*的指针接收没有警告。

这就叫数组传参的降维。

那么为什么要降维呢?

简单来说,就是为了函数调用的效率,降维成指针,就不用拷贝数组了,只用拷贝指针(4个字节)

那么降维成什么呢?

简单来说就是降维成指向内部元素类型的指针。(后续复杂指针讲解细谈)

为什么要指针和数组的访问方式相同。

上面已经说过了数组降维都是降维成指针,那么如果指针和数组访问方式不同,就会发生下面的情况。

void Show(int arr[], int num){printf("指针形式 ");for (int i = 0; i < num; i++){printf("%d ", *(arr+i));}printf("\n");}int main(){int a[5] = { 1, 2, 3, 4, 5 };int num = sizeof(a) / sizeof(a[0]);Show(a, num);printf("数组形式打印");for (int i = 0; i < num; i++){printf("%d ", a[i]);}printf("\n");Show(a, num);return 0;}

就会导致每次用用数组传参,就要用指针形式,访问数组也要用数组形式,这样就很麻烦,如果这个函数要执行多次,数组也要访问多次,那么就会导致会出错误,这样明显是不太符合使用场景的,所以最后设计时就会把数组和指针的使用方式通用。

本期总结:

首先我们说了指针和数组的在存储上区别,来深度区分指针和数组是没有任何关系的

接着我们说了数组的降维,为了铺垫数组和指针访问方式为什么相同。

接着我们说了,因为如果指针和数组访问方式不同时,就会导致一些特殊情况下,使用者不方便,增加了错误概率,所以就把它们访问方式一样了。

下期预告:

下期讲解复杂指针的知识。

下期更精彩哦~!~!~!