为何使用int (*mat)[3]初始化二维数组会触发编译警告?
为什么
int (*mat)[3]用二维列表初始化会报错? 首先得明确:int (*mat)[3]本质是一个指针,它指向的是一个包含3个int元素的一维数组,并不是二维数组本身——你可以把它理解为“二维数组的行指针”,但它本身不是数组类型。
原代码触发警告的原因
你用{{1,7,8},{1,2,3},{334,43,8}}这种二维数组的初始化列表给指针赋值,问题出在:
- 指针属于标量类型,标量只能用单个值初始化,不能用嵌套的多元素花括号列表。
- 编译器会把外层花括号当成标量的包裹,尝试把第一个元素
1(而非你预期的第一个一维数组)赋值给mat——把整数直接转成int (*)[3]类型的指针,这就触发了“指针从整数转换”的警告。 - 后面的
{1,2,3}、{334,43,8}以及内部元素,对于标量初始化来说都是多余的,所以会报“标量初始化器中存在多余元素”的警告。
正确实现方式
如果你要创建并初始化二维数组,同时用int (*mat)[3]类型的指针指向它,有两种常用方法:
方法1:先定义二维数组,再让指针指向它
// 创建并初始化真正的二维数组 int arr[3][3] = {{1,7,8}, {1,2,3}, {334,43,8}}; // arr会隐式转换成指向首行的指针,类型正好匹配int (*)[3] int (*mat)[3] = arr;
方法2:用复合字面量直接初始化指针(C99及以上支持)
如果不想单独定义数组变量,可通过复合字面量创建匿名二维数组,让指针直接指向它:
int (*mat)[3] = (int[3][3]){{1,7,8}, {1,2,3}, {334,43,8}};
这里的(int[3][3]){{...}}是复合字面量,会生成一个临时二维数组,mat指向它的首行,类型完全匹配。
内容的提问来源于stack exchange,提问作者Anant Bagaria
相关产品推荐
相关产品推荐

