首页 > 代码库 > 浅谈C中的指针和数组(六)

浅谈C中的指针和数组(六)

数组和指针,原本不想在写了,觉得这部分差不多了,但是自己在写程序的时候还是发现了一个错误。首先说一下我的要求:

给一个函数传递一个二维数组,然后我想在这个函数里面计算这个数组的行数。

写个类似的错误DEMO代码弄上来:

#include <stdio.h>#include <stdlib.h>void func(int a[][3]){    printf("%p\n", a);    printf("%p\n", a[0]);    printf("%p\n", &a);    printf("%d\n", sizeof(a));    printf("%d\n", sizeof(a[0]));    printf("%d\n", sizeof(a));    printf("%d\n", sizeof(a)/sizeof(a[0]));    printf("%d\n", a[1][2]);}int main(){    int a[2][3] = {{1,2,3},{4,5,6}};        printf("%d\n", sizeof(a));    printf("%d\n", sizeof(a[0]));    printf("%d\n", sizeof(a)/sizeof(a[0]));    func(a);    system("pause");    return 0;}
数组名本身是个地址常量,但是某些特殊情况下它的语义可以发生改变。例如sizeof(a),这时a表示整个数组对象(这里指语法对象,不是指类的实例)而不是这个常量本身。基于这个语义,对数组名取地址也是合法的,对于数组a来说&a的结果等于a这个地址常量本身的值。这是C/C++标准委员会为了维护语法对象a作为一个左值(l-value)总可以取地址这条原则的妥协。
#include <stdio.h>int main(void){ char str[] = "world"; char * pstr = "world"; printf("%d %d",sizeof(str),sizeof(pstr)); getchar(); return 0;}
运行结果6 4。
解释:
char str[] = "world";
这里初始化不限定长度,而"world"包含结束符‘\0‘后为6个字符,因此初始化str的长度是6;又因为char数组中每个元素(char变量)占用1个字节的空间,所以str[]数组的大小是6字节。
char *pstr = "world";
由于pstr是指针,无论是否指向字符串,指向什么字符串,sizeof(pstr)等于sizeof(int),32位平台上等于4。
造成差别的原因:
这里char str[] = "world";声明并定义了一个数组str[](当然,C语言的语法不允许在定义之外这样引用整个数组,以下这样的写法只是为了区分语义),之后标识符str有双重语义:一是类型为char* const的地址常量,它的值等于数组中首个元素的地址,即str等价于(char* const)&str[0];二是表示整个str[]数组这个语法对象。在sizeof(str)中,str表示的含义是str[],因此返回整个数组的大小(这个大小在之前的数组定义中已经确定了);而pstr只是个指针,sizeof(pstr)只能返回指针本身占用的字节数而不能确定为它指向的内容分配的空间的大小。
(注意,地址常量绝不是指针,类型不同!虽然在函数的参数传递过程中,地址常量可以退化成对应的指针。这里LZ和2L显然由于这个错误理解导致对数组的sizeof()结果判断有误。)
关于数组名语义规定以及“数组名实际上就表示一个指针(

错的!!!!)”的原因 以后需要注意哈···

浅谈C中的指针和数组(六)