如何正确获取unsigned char数组长度并打印全部十六进制值
问题根因
C语言中数组名作为函数参数传递时,会自动退化为指向数组首元素的指针,函数内部无法感知传入的原始数组的长度。你代码中sizeof(raw_instr)实际是计算指针的内存大小:32位编译环境下为4字节,64位环境下为8字节,和数组实际长度无关,所以才会出现只打印4个元素的问题。
推荐解决方案
- 方案1:调用函数前计算数组长度,作为参数同步传入(最通用,推荐使用)
调整函数定义,新增长度参数,调用前在数组定义的作用域内计算长度传入,示例代码如下:
// 调整后的打印函数 void print_hex_instr(unsigned char *raw_instr, size_t len) { if(raw_instr[0]==0x68){ printf("%zu\n", len); for(int i=0; i < len; i++){ printf("%x ", raw_instr[i]); } printf("\n"); } } // 调用示例 unsigned char inst1[5] = {0x68,0x10,0x3f,0x00,0x00}; // 直接计算数组长度传入,unsigned char单元素占1字节,可直接写sizeof(inst1) // 通用兼容其他类型数组的写法为 sizeof(inst1) / sizeof(inst1[0]) print_hex_instr(inst1, sizeof(inst1));
- 方案2:固定长度数组形参(仅适用于固定长度数组场景)
如果你的业务场景中所有传入的数组长度都是固定的,可以将形参声明为指向固定长度数组的指针,就能在函数内用sizeof获取长度:
// 仅支持长度为5的unsigned char数组传入 void print_hex_instr(unsigned char (*raw_instr)[5]) { size_t len = sizeof(*raw_instr); // 此处len值为5 if((*raw_instr)[0]==0x68){ printf("%zu\n", len); for(int i=0; i < len; i++){ printf("%x ", (*raw_instr)[i]); } printf("\n"); } } // 调用示例 unsigned char inst1[5] = {0x68,0x10,0x3f,0x00,0x00}; print_hex_instr(&inst1);
- 方案3:设置数组哨兵值(仅适用于数据不会包含哨兵值的特殊场景)
约定数组末尾用一个不会出现在业务数据中的特殊值作为结束标记,函数内遍历到哨兵值就停止,不需要额外传长度参数,比如约定哨兵为0xFF:
void print_hex_instr(unsigned char *raw_instr) { if(raw_instr[0]==0x68){ int i = 0; while(raw_instr[i] != 0xFF) { printf("%x ", raw_instr[i]); i++; } printf("\n"); } } // 数组定义末尾加哨兵 unsigned char inst1[] = {0x68,0x10,0x3f,0x00,0x00, 0xFF}; print_hex_instr(inst1);
内容的提问来源于stack exchange,提问作者Nattapat
相关产品推荐
相关产品推荐

