你的月亮我的C(六):指针和数组的那些事

先来看几个问题,一边从问题中入手,一边看看指针和数组之间的那些事:

1、char arr[ ]和char *arr是等价的吗?

答:不是。看下指针和数组的定义:数组是一个用同一类型的多个连续元素组成的事先分配好的内存块。指针是一个可以对任何数据元素的引用。所以数组的定义char arr[ n ]表示申请n个字符内存的位置,这块内存的名字为arr,也就是说有一块名为“arr”的内存“块”,里面有n个字符的容量。而指针char arr*表示申请一个名为arr的指针,这个指针可以指向任何的地方,或者指向NULL。看下面这张图或许你会更清楚:

  1. 指针和数组等价到底是什么意思?

答:引用Steve Summit的话:“多数的数组引用都会退化为数组的第一个元素的指针,这是C语言中指针和数组“等价”的基础。”指针和数组“等价”但并不是说它们相同,指针和数组指针不能互换。引用Wayne Throop的话:“在C语言中只是指针算术和数组下标运算等价,指针和数组是不同的。”

也就是说,当你对数组进行操作时(其实从你一开始定义一个数组时),编译器就会生成一个指向数组第一个元素的指针,这就是上面说的数组的退化。

  1. 既然指针和数组不同,为什么在函数的形参中,指针和数组声明可以互换?

答:因为数组会被马上退化为指针,所以数组实际上没有被传进去函数里,函数接收到的其实是一个指针,例如:

Int fun(char arr[ ])

{

}

其实在编译器中被当作了指针来处理,它等于:

Int fun(char *arr)

{

}

  1. 为什么不能用“=”给数组赋值?

char arr[ 10 ];

arr=”abcde”;

答:因为上面所说的,“多数的数组引用都会被退化为数组的第一个元素的指针。”所以,你不能把数组作为一个整体来操作。当你使用一个数组的名称的时候,你得到的是一个指针而不是数组。例如arr[ 4 ]其实会被等价于*((arr)+(4)),所以,如果你想把一个数组复制其内容,你可以使用strcpy:

strcpy(arr, “abcde”);

有人会问了,既然不能用“=”给数组赋值,那么为什么下面这段代码是可以的?

Int fun(char arr[ ])

{

If (arr[ 0] ==’\0’) {

arr=”justin”;

}

}

因为数组在做为形参传进去函数时会被立刻退化成指针呀!上面也说了,数组实际上没有被传进去函数里,函数接收到的其实是一个指针,所以,在fun函数中形参char arr[ ]被编译器换成了char *arr指针,所以对于指针操作arr=”justin”是可以的。

  1. 为什么arr[ 3 ]和3[ arr ]输出是一样的?为什么可以写3[ arr ]?

答:在C语言中,数组名和下标是可以互换的,还记不记得上面第4问所说的:“arr[ 4 ]其实会被等价于*((arr)+(4))。”其实,数组的下标操作符实际上是个指针操作符arr[ 3 ]等价于3[ arr ]。是因为:

arr [ 3 ]=*((arr)+(3));

而*((arr)+(3))=*((3)+(arr));(加法交换律)

所以arr[ 3 ]=3[ arr ]。

  1. 为什么int arr[ 8 ]; scanf(“%d”, arr);数组arr前不用加&?

答:我们知道数组的引用会被退化成指针,所以对数组arr引用时,等于是生成了一个int型的指针,指向了数组的第一个元素。而对&arr引用是,等于是生成了一个“8个int型的数组”的指针,指向整个arr数组。所以对整个数组做scanf操作明显是不行的。

最后总结一下,指针和数组的那些事:

  1. 数组是一个用同一类型的多个连续元素组成的事先分配好的内存块。指针是一个可以对任何数据元素的引用。数组定义后便自动分配空间,但是不能重新分配空间或者说改变空间大小。指针在定义后必须被赋值来指向一个分配好的空间,通常使用malloc。
  2. 指针和数组并不相同。平常说的指针和数组“等价”,是因为多数的数组引用都会退化为数组的第一个元素的指针,这是C语言中指针和数组“等价”的基础。
  3. 数组下标的操作符[ ]实际上是个指针操作符,所以为什么指针也可以当作数组来使用。例如动态数组分配中:

Int *p=(int*)malloc(100*sizeof(int));

P[ 2 ]=5;

Printf(“%d\n”, p[ 2 ]);

这样是可以的,把指针申请(指向)一块内存后,指针本质上也就是一个数组。

  1. arr[ 3 ]和3[ arr ]一样,因为数组被退化成指针了嘛,就是这样:

因为:arr [ 3 ]=*((arr)+(3));

而:*((arr)+(3))=*((3)+(arr));(加法交换律)

所以:arr[ 3 ]=3[ arr ]。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值