C语言中int类型Ragged arrays初始化报GCC警告问题咨询
问题解惑:为什么
int *numbers[] = { {1,2,3}, {4,5,6} };会触发编译警告 先明确两种场景的本质差异:
你用
char *fruits[] = {"Apple", "Pear"};是合法的,因为字符串字面量(比如"Apple")本质是**const char类型的数组**,在表达式中会自动"退化"成指向数组首元素的指针(也就是char*类型,C允许这种隐式转换),所以每个字符串字面量都能匹配fruits数组元素的char*类型,这确实是行长度可变的Ragged Arrays(不规则数组)。而
int *numbers[] = { {1,2,3}, {4,5,6} };的问题在于:{1,2,3}是一个数组初始化列表,但numbers的元素是int*(指针属于标量类型)。C语言里,标量初始化时只能用单个值,给标量用花括号包裹的多值初始化器属于"给标量用了数组式初始化",这就触发了GCC的braces around scalar initializer警告——更关键的是,普通整数数组的初始化列表不会像字符串字面量那样自动退化成指针,编译器无法把{1,2,3}转换成合法的int*值。
正确的写法
如果你想创建整数类型的不规则数组(元素是指向不同长度int数组的指针),有两种合法方式:
方式1:先定义独立数组,再让指针指向它们
// 先定义两个长度不同的int数组 int nums1[] = {1, 2, 3}; int nums2[] = {4, 5}; // 可以故意设为不同长度,体现不规则特性 // 让numbers的元素指向这两个数组的首地址 int *numbers[] = {nums1, nums2};
方式2:使用C99引入的复合字面量(更简洁)
复合字面量可以直接在初始化时创建匿名数组,并自动退化成指针:
int *numbers[] = { (int[]){1,2,3}, (int[]){4,5} };
这里的(int[]){1,2,3}是匿名int数组,会自动转换成指向首元素的int*指针,完美匹配numbers数组的元素类型,编译无警告,且能实现你想要的不规则数组效果。
内容的提问来源于stack exchange,提问作者Jeff Favret
相关产品推荐
相关产品推荐

