标题:[实践OK]为何数组的首地址当指针传入函数时,得传入数组的长度之sizeof函数,sizeof(数组名)和sizeof(指针)的区别,及fwrite里的第二第三参数的用法。 出处:向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除 时间:Thu, 22 Feb 2018 09:02:03 +0000 作者:jackxiang 地址:https://jackxiang.com/post/9645/ 内容: 背景:为何数组的首地址当指针传入函数时,得传入数组的长度?在函数体内的其实是通过数组名初始化的指针形参,故不能在函数中通过 sizeof(指针形参)/sizeof(数组元素类型) 来计算数组长度。所以一般将数组名作为形参传入函数时,也会同时传递一个数组长度的参数。为何指针长度是8位,而不是4位?因为系统是64位的(8字节,64位系统)。 数组名一旦传入函数,再用sizeof(数组名,也就是首地址),其得出的值变为8了,不再是1024了,实践如下: vi fwrite.c #include #include int returnArrPointerLen(char * bufferArrPointer){ // 这个bufferArrPointer尽管传入的是数组的首地址,但是它的sizeof(bufferArrPointer)不是1024,而是8了,所以得入数组的长度值。 return sizeof(bufferArrPointer); } int main(){ char *buf; char buffer[1024]; printf("1)直接在变量申明段里访问数组长度值:sizeof的数组名buffer=%d\n",sizeof(buffer)); int recvlen; strcpy(buffer,"jackTestWriteFile's function named fwrite。"); printf("2)!!returnArrPointerLen函数返回buffer数组首地址到函数里后长度值就不等于1024了,等于:%d\n",returnArrPointerLen(buffer)); buf = buffer; printf("3)returnArrPointerLen函数传入指向数组buffer首地址返回buffer长度和申明数组长度不一样等于%d\n",returnArrPointerLen(buf)); printf("4)sizeof buf=%d\n",sizeof(buf)); printf("5)strlen buf=%d\n",strlen(buf)); buf = buf+10; printf("6)sizeof buf=%d\n",sizeof(buf)); printf("7)strlen buf=%d\n",strlen(buf)); recvlen=strlen(buffer); FILE *dst; dst=fopen("/tmp/out.dat","a+"); if(dst==NULL){ printf("cant'to open destination file\n"); return 0; } fwrite(buf,recvlen,1,dst); fclose(dst); } #./fwrite 1)直接在变量申明段里访问数组长度值:sizeof的数组名buffer=1024 2)!!returnArrPointerLen函数返回buffer数组首地址到函数里后长度值就不等于1024了,等于:8 3)returnArrPointerLen函数传入指向数组buffer首地址返回buffer长度和申明数组长度不一样等于8 4)sizeof buf=8 5)strlen buf=44 6)sizeof buf=8 7)strlen buf=34 总之,一旦将数组首地址传入函数,那么其长度就变成了指针长度了,而32位系统和64位系统指针分别对应的是4和8: #include "stdio.h" int main(void) { int number[5] = {1,2,3,4,5}; int index = 0; int *p = &number[0]; int count = sizeof(number) / sizeof(number[0]);//得出了5,但是这个如果放到函数里,也就变成指针大小了。参考:https://zhuanlan.zhihu.com/p/24965911 printf("1)指向数组首地址,数组的长度是: %d\n", sizeof(number));//等于20,于是想除以4,于是用: sizeof(number) / sizeof(number[0] printf("2)用指针指向数组的首地址长度是: %d\n", sizeof(p)); printf("3)试图求下数组第一个键值的空间大小sizeof(number)=%d\n",sizeof(number[0])); printf("4)再试图通过sizeof(number)/sizeof(number[0]得出5? %d\n", count); printf("数组的元素分别是:\n"); //for(index = 0;index < sizeof(p); index++) for(index = 0;index < count; index++)//此路不通 //for(index = 0;index < sizeof(number); index++) { printf("%d ", number[index]); } printf("\n"); return 0; } #./sizeofarr 1)指向数组首地址,数组的长度是: 20 2)用指针指向数组的首地址长度是: 8 3)试图求下数组第一个键值的空间大小sizeof(number)=4 4)再试图通过sizeof(number)/sizeof(number[0]得出5? 5 数组的元素分别是: 1 2 3 4 5 在c/c++中我们一般都用 sizeof(数组名)/sizeof(数组元素类型) 来计算数组的长度,其中 sizeof(数组名) 计算的是数组占用的存储大小。同时,一般我们认为数组名和指针就是一回事,最近写程序时将数组名作为指针形参传入函数,想在函数中用 sizeof(指针形参)/sizeof(数组元素类型) 来计算数组长度时却出了错,最后发现原来是sizeof(数组名)和sizeof(指针)的区别导致的,于是写了段代码测试了一下: #include void fun(int *E) { std::cout<<"函数指针形参:"<