You need to enable JavaScript to run this app. 嵌入式C开发:函数内用sizeof获取传入数组大小与外部结果不一致问题
优惠活动
大模型
产品
解决方案
定价
更多

嵌入式C开发:函数内用sizeof获取传入数组大小与外部结果不一致问题

函数内外数组计算结果不一致的本质原因

C语言存在数组形参降级规则:当数组类型被声明为函数形参时,编译器会自动将其等价转换为指向数组首元素的指针,完全丢失“数组长度”的类型信息。

对应你的运行结果完全匹配这个规则:

  • 主函数中val_array是独立的int[3]实体数组,因此sizeof(val_array)计算的是整个数组的总字节数,即3个int * 4字节 = 12字节,和输出一致
  • 传入校验函数后,形参int value_array[]在编译阶段等价于int *value_array,此时sizeof(value_array)计算的是指针本身的大小:32位环境下指针长度为4字节,也就是你看到的函数内输出Size of array:4的根源

基于这个规则,你代码中使用的NELEMS宏在函数内部计算时,实际等价于sizeof(指针)/sizeof(数组首元素)= 4/4 =1,因此循环只会遍历数组的第一个元素,不会走到值为1000的第二个元素,最终跳过数组值匹配逻辑,进入范围判断分支。而你的范围数组是{0,255},1000不在这个开区间内,才触发了“数值不合法”的错误提示。

你代码中原本写的sizeof(value_array) >= sizeof(range_array)判断逻辑从根上就不成立:两个都是指针类型,比较指针长度没有任何业务意义,之前能走通分支仅仅是因为32位环境下所有指针长度都是4字节,属于巧合。

正确的代码调整方案

嵌入式开发场景下最稳妥、兼容性最好的修改方式,是在函数形参中显式传入数组的实际长度,补全数组降级丢失的长度信息:

  • 第一步:修改校验函数的形参列表,把两个数组的长度作为独立参数传入,函数内部所有依赖sizeof算数组大小的逻辑,全部替换为传入的长度参数
    #define NELEMS(x)  (sizeof(x) / sizeof(x[0]))
    int check_val_is_valid(int32_t field_val, 
                           int value_array[], size_t value_array_len,
                           int32_t range_array[], size_t range_array_len)
    {     
        size_t size = (value_array_len >= range_array_len) ? value_array_len : range_array_len;
        printf("实际参与校验的数组长度: %zu\n", size);
        
        int i=0;
        for(i=0; i < value_array_len; i++) 
        {
            printf("遍历校验值: %d\n", value_array[i]);
            if(value_array[i] == field_val) 
            {
                return 1; 
            }
        }
        // 增加长度边界校验,避免数组越界访问;同时将开区间判断调整为业务常用的闭区间逻辑
        if (range_array_len >=2 && field_val >= range_array[0] && field_val <= range_array[1])
        {
            return 1;
        }
        return 0; 
    }
    
  • 第二步:修改主函数的调用逻辑,利用主函数中可以正确获取数组长度的特性,把长度值传入校验函数
    int val = 1000;
    int val_array[] = {1, 1000, 1234};
    int32_t rang_array[] = {0, 255};
    // 调用时显式传入两个数组的真实长度
    if (!check_val_is_valid(val, 
                            val_array, NELEMS(val_array),
                            rang_array, NELEMS(rang_array)))
    {
        printf("The val is not valid!");
    }
    
  • 额外规范提示:C语言中不推荐在函数内部对形参数组使用sizeof来计算长度,这种写法从语法层面就永远得不到正确结果,所有跨函数传递数组的场景,必须配套传递数组的实际长度,同时增加长度合法性校验避免越界访问。

内容的提问来源于stack exchange,提问作者Marcusnh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.10 08:54:11