如何动态计算unsigned char数组长度?无需传入函数原型
动态计算数组大小(无需手动传入长度)
我太懂这种痛点了——每次调用函数还要手动敲数组长度,不仅麻烦还容易写错,尤其是像aes_key这种固定长度但又不想硬编码的数组对吧?在C/C++里直接让函数“自动”获取数组大小确实有点绕,因为数组作为函数参数时会退化成指针,普通的sizeof根本拿不到原始数组的长度。不过有几个靠谱的方案能解决这个问题,我给你拆解一下:
方案1:C语言下用编译期宏(最常用)
用宏在编译期直接计算数组大小,完全不需要运行时开销,而且能自动适配不同类型的数组:
// 通用数组大小宏,类型安全(如果传指针会触发警告/报错) #define ARRAY_SIZE(arr) \ (sizeof(arr) / sizeof((arr)[0])) // 示例:直接计算你的aes_key大小 unsigned char aes_key[16] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}; size_t key_size = ARRAY_SIZE(aes_key); // 结果是16,编译期就确定了
如果想把这个和函数结合,不用手动传长度,可以再封装一层宏来自动传递大小:
#include <stdio.h> #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0])) #define PROCESS_ARRAY(arr) process_array(arr, ARRAY_SIZE(arr)) void process_array(const unsigned char* data, size_t len) { // 这里写你的数组处理逻辑,比如加密操作 printf("Processing array with length: %zu\n", len); } // 调用的时候直接写,不用管长度: PROCESS_ARRAY(aes_key);
注意点
这个宏只能在数组的原始定义作用域里用,如果数组已经被转换成指针(比如传给普通函数之后),sizeof(arr)会变成指针的大小,结果就错了。
方案2:C11及以上用_Generic做类型安全检查
上面的宏如果不小心传了指针(比如unsigned char* ptr = aes_key; ARRAY_SIZE(ptr);),会得到错误的结果(比如8或4,取决于系统指针大小)。用C11的_Generic可以做类型检查,传指针直接编译报错:
#define SAFE_ARRAY_SIZE(arr) _Generic((arr), \ unsigned char*: (void)0, /* 传指针就触发编译错误 */ \ unsigned char[]: sizeof(arr)/sizeof((arr)[0]) \ )
这样如果误传指针,编译器会直接报错,避免隐性bug。
方案3:C++下用模板函数(最优雅)
如果你的代码是C++环境,用模板函数可以完全不用手动传长度,编译器会自动推导数组的大小:
#include <iostream> // 模板函数自动推导数组长度N template <size_t N> void process_aes_key(const unsigned char (&key)[N]) { std::cout << "AES key length: " << N << std::endl; // 这里写你的加密逻辑,N就是数组的真实大小 } // 调用的时候直接传数组,不用管长度: unsigned char aes_key[16] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}; process_aes_key(aes_key);
这个方法完全类型安全,而且代码最简洁,只要是C++环境首选这个。
内容的提问来源于stack exchange,提问作者damadam
相关产品推荐
相关产品推荐

