zoukankan      html  css  js  c++  java
  • c中自定义函数通过sizeof来输出数组的长度为何不正确?【原创】

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


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

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

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

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

    解决办法:
    第一种办法:
    把数组作为参数传入到数组的同时呢,也传入该数组的长度进去。不过该办法需要在函数外获取该数组的长度才传进去,略显麻烦。
    第二种办法:(推荐)
    使用宏定义
    如:
    #include <stdio.h>  
    #define ARR_LENGTH(arr)    sizeof(arr)/sizeof(arr[0])
    
    int main(){
        double arr[]={1.78, 1.77, 1.82, 1.79, 1.85, 1.75, 1.86, 1.77, 1.81, 1.80};
        printf("宏定义里面的数组长度为%d
    ",ARR_LENGTH(arr));
        return 0;
    }

    第三种办法:(目前不知如何实现)
    template <size_t N>
    long calc(long (&array)[N]) // 利用模板传递参数 array是数组的引用
    {
        long res = 0L;
    
        for (size_t i = 0;i < N;i ++) {
            res += array[i];
        }
    
        return res;
    }
    
    int main()
    {
        long longarr[] = {1, 23, 4, 45, 46, 57,};
    
        long sum = calc(longarr);
    }

    补充:第三种办法是网友的建议,C++可以用vector等容器避免大部分数组的操作,对于字符数组也有string可以替代,也有可以传递数组大小的奇迹淫巧。如果你需要计算数组长度的函数,可以使用宏定义 或者 如果是C++,也用相应的模板技巧,这比宏定义安全。
  • 相关阅读:
    Hanoi塔
    采药
    进制转换(大数)
    Load Balancing with NGINX 负载均衡算法
    upstream模块实现反向代理的功能
    epoll
    在nginx启动后,如果我们要操作nginx,要怎么做呢 别增加无谓的上下文切换 异步非阻塞的方式来处理请求 worker的个数为cpu的核数 红黑树
    粘性会话 session affinity sticky session requests from the same client to be passed to the same server in a group of servers
    负载均衡 4层协议 7层协议
    A Secure Cookie Protocol 安全cookie协议 配置服务器Cookie
  • 原文地址:https://www.cnblogs.com/linewman/p/9918135.html
Copyright © 2011-2022 走看看