前面两篇博文分别介绍了数组与指针的知识,本篇将主要介绍两者的联系与区别。希望对初学者有所帮助。
数组与指针的共同点
分别定义一个数组与一个指针变量,如下:
int sArr[10] = {‘a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’,’i’,0};
char *ptr = ‘abcdefghi’;
两者均可通过下标访问
/*通过下标访问*/
printf("sArr[3] = %c\n",sArr[3]);
printf("ptr[3] = %c\n",ptr[3]);
两者均可通过间接访问运算符访问
/*通过间接访问运算符*访问*/
printf("*(sArr+3) = %c\n",*(sArr+3));
printf("*(ptr+3) = %c\n",*(ptr+3));
数组与指针的不同
指针变量是左值,数组名是右值
指针是左值(除非声明为const),其值可以更改,数组名是右值,其值不可以更改,具体操作如下:
/*指针变量是左值,数组名是右值*/
char sArr[10] = {'a','b','c','d','e','f','g','h','i',0};
char *ptr = "abcdefghi";
ptr = sArr;//正确,指针变量ptr是左值
sArr = ptr;//错误,数组名是指针常量,其值不可修改
指针字节长度与数组字节长度不是一个概念
我们已经知道,任何一个指针变量的长度都是机器字长,一般是4字节,而数组虽然是一个指针常量,但其字节长度并不一定为4,具体如下:
/*指针变量所占字节长度相等,一般为4 */
char *ptr = "abcdefghi";
int *ptr2 = NULL;
printf("sizeof(ptr) = %d\n",sizeof(ptr));//Len = 4
printf("sizeof(ptr2) = %d\n",sizeof(ptr2));//Len = 4
/*数组名所占字节长度:类型长度乘以元素个数*/
char sArr[10] = {'a','b','c','d','e','f','g','h','i',0};
int iArr[10] = {0};
printf("sizeof(sArr) = %d\n",sizeof(sArr));//Len = 1 * 10
printf("sizeof(iArr) = %d\n",sizeof(iArr));//Len = 4 * 10
指针数组与数组指针
指针数组:即存储指针的数组,数组元素都是指针
数组指针:即指向数组的指针
出了概念上的区别,还要主要他们使用上的不同,如下:
int * iArr[6] 指针数组
含义:表示存储指针的数组
元素表示:*(iArr[i]),也可用*iArr[i]表示,因为[]的优先级高于*
int (*ptr)[6] 数组指针
含义:指向数组首地址的指针
元素表示:(*ptr)[i]
指针与数组经典题集分析
-
下列输出字符串的方法可行吗?
/*输出字符串的方法可行性分析*/
char sArr[5] = {'a','b','c','d','e'};
printf("sArr = %s\n",sArr);
以上输出字符串的方法不可行,字符串的特点是遇到空字符结束,由于数组的长度与字符串的实际长度一致,导致字符串并不能正常输出,很有可能在字符e后继续输出其他字符,直到遇到空字符为止。
建议:当用数组存储字符串时,数组长度至少要比字符串长度大1,用于存储空字符。
-
当对作为函数形参的数组传递参数时,对其sizeof可以求的该数组长度吗?
void strLen(char arr[100])
{
printf("sizeof(arr) = %d\n",sizeof(arr));//sizeof(arr) = 4;
}
不可以,无论数组还是指针作为参数时接收的都是地址,由于地址占机器字长(一般占4个字节),所以用数组作为函数参数会退化为一般指针,其长度为机器字长。
【总结】
-
指针变量是左值,数组名是右值
-
数组存放字符串时要确保数组长度至少比字符串本身长度大一个字节
-
数组作为函数参数传递时退化为一般指针,其长度占机器字长个字节(一般4字节)
指针与数组是重点也是难点,其中涉及好多易混淆的地方,所以建议大家学习中勤思考,多上机、勤总结。