C语言中如何正确获取char**类型字符串数组的长度
解决char**数组长度获取与整数判断函数的问题
嘿,我来帮你搞定这两个困扰你的问题!
一、为什么你用sizeof获取不到char**数组的正确长度?
在C语言里,当你把一个数组(比如char* str_arr[] = {"hello", "world", NULL};)传递给函数作为char**参数时,数组会退化为指针。这时候sizeof(str)得到的是指针本身的大小(比如在64位系统上是8字节),而不是整个数组的总字节数。所以你用sizeof(str)/sizeof(str[0])计算出来的永远是8/8=1(64位)或者4/4=1(32位),完全不是你想要的数组元素个数。
解决方法:两种常见思路
1. 传递数组时额外传入长度参数
这是最直接的方式,在调用函数的时候把数组长度一起传进去:
// 调用示例 char* str_arr[] = {"hello", "world"}; int len = sizeof(str_arr)/sizeof(str_arr[0]); // 这里在数组定义的作用域内可以正确计算 my_function(str_arr, len); // 函数修改为 int my_function(char** str, int arr_len) { // 直接使用arr_len即可 if (arr_len < 2) return 0; // ... 后续逻辑 }
2. 用哨兵值(NULL)标记数组结尾
如果你不想额外传长度,可以约定数组的最后一个元素为NULL,然后通过遍历到NULL来计数:
// 定义数组时加上NULL哨兵 char* str_arr[] = {"hello", "world", NULL}; // 编写获取长度的函数 int get_arr_length(char** str) { int count = 0; if (!str) return 0; // 处理空指针输入 while (str[count] != NULL) { count++; } return count; } // 使用示例 int len = get_arr_length(str_arr); // 会返回2,跳过最后的NULL
这种方式更灵活,很多C标准库的函数(比如exec系列)也用这种模式。
二、修正你的整数判断函数
你的原函数有几个明显的错误,我帮你修正并解释:
原函数的问题:
- 用
sizeof(str)/sizeof(str[0])获取长度,这个刚才已经说过完全不可行 - 判断
isdigit时传的是str(char**类型),而不是str[1]的单个字符 - 没有检查
str[1]是否存在,直接访问会导致越界错误
修正后的函数(基于哨兵值的方式):
#include <ctype.h> #include <string.h> // 先实现哨兵模式的长度获取函数 int get_arr_length(char** str) { int count = 0; if (!str) return 0; while (str[count] != NULL) { count++; } return count; } int my_function(char** str) { // 处理空输入或空数组 if (!str || str[0] == NULL) { return 0; } int arr_len = get_arr_length(str); // 检查是否存在第二个元素 if (arr_len < 2) { return 0; } char* second_element = str[1]; int str_len = strlen(second_element); // 遍历每个字符判断是否为数字 for (int i = 0; i < str_len; i++) { // 转成unsigned char避免isdigit处理负数字符的未定义行为 if (!isdigit((unsigned char)second_element[i])) { return 0; } } return 1; }
关键修正点:
- 替换了错误的长度计算逻辑,改用哨兵遍历获取真实长度
- 增加了对
str[1]是否存在的判断,避免数组越界访问 - 修正了
isdigit的参数,改为second_element[i](即str[1][i]),并且强制转成unsigned char——因为isdigit要求参数是unsigned char或者EOF,如果你的char是有符号类型,负数字符会引发未定义行为 - 完善了空指针和空数组的边界检查
这样修改后,函数就能正确判断第二个元素是否为纯整数了。
内容的提问来源于stack exchange,提问作者p20xx




