c中自定义函数通过sizeof来输出数组的长度为何不正确?

这两天,在学习C语言的时候遇到一个bug。后来就在segmentfault提问,通过网友的回答也就解决了这个问题。提问的问题链接是: c中自定义函数通过sizeof来输出数组的长度为何不正确?


在C语言中,获取数组的长度大小,即元素个数一般用 sizeof(arr)/sizeof(arr[0])来表示。即:
  1. #include <stdio.h>    
  2. int main(){  
  3.     double arr[]={1.78, 1.77, 1.82, 1.79, 1.85, 1.75, 1.86, 1.77, 1.81, 1.80};  
  4.     int length = sizeof(arr)/sizeof(arr[0]);  
  5.     printf(”main里面的数组长度为%d\n”,length);   //正常输出, 10  
  6.     return 0;  
  7. }  

结果输出:会正常输出元素的个数的。

但如果写成一个函数的方式,把数组作为函数的参数传入的话。即:
  1. <pre name=“code” class=“cpp”>#include <stdio.h>    
  2.   
  3. int arr_str(double a[]) {  
  4.     int len=sizeof(a)/sizeof(a[0]);  //1    
  5.     return len;  
  6. }  
  7.   
  8. int main(){  
  9.     double arr[]={1.78, 1.77, 1.82, 1.79, 1.85, 1.75, 1.86, 1.77, 1.81, 1.80};  
  10.     printf(”arr_str里面的数组长度为%d\n”,arr_str(arr));  
  11.     return 0;  
  12. }  
结果输出:显示不了数组的长度,而是1。

原因在于:第一,在c中,数组在作为参数的时候就退化为指针,对一个地址来取大小呢,如果是32位系统的话即为4,如果是64位系统的话为8,所以呢,在函数中sizeof获取的是指针的长度而不是数组的长度。第二呢,在函数中,sizeof的处理时间的在编译期,也就是说对于动态生成的数组大小是不能用sizeof来算出来的。

解决办法:
第一种办法:
把数组作为参数传入到数组的同时呢,也传入该数组的长度进去。不过该办法需要在函数外获取该数组的长度才传进去,略显麻烦。
第二种办法:(推荐)
使用宏定义
如:

  1. #include <stdio.h>    
  2. #define ARR_LENGTH(arr)    sizeof(arr)/sizeof(arr[0])  
  3.   
  4. int main(){  
  5.     double arr[]={1.78, 1.77, 1.82, 1.79, 1.85, 1.75, 1.86, 1.77, 1.81, 1.80};  
  6.     printf(”宏定义里面的数组长度为%d\n”,ARR_LENGTH(arr));  
  7.     return 0;  
  8. }  

第三种办法:(目前不知如何实现)
  1. template <size_t N>  
  2. long calc(long (&array)[N]) // 利用模板传递参数 array是数组的引用  
  3. {  
  4.     long res = 0L;  
  5.   
  6.     for (size_t i = 0;i < N;i ++) {  
  7.         res += array[i];  
  8.     }  
  9.   
  10.     return res;  
  11. }  
  12.   
  13. int main()  
  14. {  
  15.     long longarr[] = {1, 23, 4, 45, 46, 57,};  
  16.   
  17.     long sum = calc(longarr);  
  18. }  

补充:第三种办法是网友的建议, C++可以用vector等容器避免大部分数组的操作,对于字符数组也有string可以替代,也有可以传递数组大小的奇迹淫巧。如果你需要计算数组长度的函数,可以使用宏定义
或者 如果是C++,也用相应的模板技巧,这比宏定义安全。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值