如何访问作为 typedef 的二维数组
How access 2-D array which is a typedef
如果我有以下代码
typedef float a[5][2];
a x = {(40,30),(46,30),(56,30),(58,30),(60,30)};
编译成功。我在访问上述数组 x 的元素时遇到问题。
for(i=0;i<5;i++)
{
for(j=0;j<2;j++)
{
printf("\nx[%d][%d]=%f",i,j,*x[z++]);
}
}
以上代码输出
x[0][0]=30.000000
x[0][1]=30.000000
x[1][0]=30.000000
x[1][1]=0.000000
x[2][0]=0.000000
x[2][1]=0.000000
x[3][0]=0.000000
x[3][1]=0.000000
x[4][0]=-1.781255
x[4][1]=0.000000
编译时出现警告
warning: left-hand operand of comma expression has no effect
[-Wunused-value]
因为
a x = {(40,30),(46,30),(56,30),(58,30),(60,30)};
和
a x = {30, 30, 30, 30, 30};
相同。
你要的是
a x = {{40,30},{46,30},{56,30},{58,30},{60,30}};
(大括号代替圆括号)
或更好
a x = {{40.f,30.f},{46.f,30.f},{56.f,30.f},{58.f,30.f},{60.f,30.f}};
一旦您声明了对象 x,它就像普通的二维数组一样工作。但是,我相信您调用 printf() 的最后一个参数应该传入一个二维数组。因此,而不是:
printf("\nx[%d][%d]=%f",i,j,*x[z++]);
*x[z++] 应该是这样的:
printf("\nx[%d][%d]=%f",i,j,x[i][j]);
您似乎将一个一维数组作为最后一个参数传入。请记住,如果 z 是您声明的变量,则在示例中显示声明非常有价值。
代码有几个问题,但我从最激烈的开始。
数组下标无效
*x[z++]
与 x[z++][0]
相同。假设 z
开头是 0
,您正在访问数组元素 x[0][0]
、x[1][0]
、x[2][0]
、...、x[8][0]
和x[9][0]
。您正在越界访问,因此得到 未定义的行为。打印的最后 5 个值是垃圾。
只需使用语法 x[i][j]
.
错误的数组初始化器
(40,30)
将扩展为 30
,因为您没有使用正确的大括号。代码不违法,但不会给出你想要的结果。您的代码等于:
a x = {{30, 30}, {30, 30}, {30, 0}, {0, 0}, {0, 0}};
正确的初始化器应该是这样的:
a x = {{40.0f, 30.0f}, {46.0f, 30.0f}, {56.0f, 30.0f}, {58.0f, 30.0f}, {60.0f, 30.0f}};
请注意我是如何使用后缀 .0f
来表示这些是浮点数的。这不是绝对必要的,但使用正确的类型是个好习惯。
在 typedef 后面隐藏数组
这不是错误,但将指针或数组隐藏在 typedef
后面并不是一个好习惯。数组在某些情况下表现异常(例如数组衰减为指针),这可能会让程序员感到惊讶。
如果我有以下代码
typedef float a[5][2];
a x = {(40,30),(46,30),(56,30),(58,30),(60,30)};
编译成功。我在访问上述数组 x 的元素时遇到问题。
for(i=0;i<5;i++)
{
for(j=0;j<2;j++)
{
printf("\nx[%d][%d]=%f",i,j,*x[z++]);
}
}
以上代码输出
x[0][0]=30.000000
x[0][1]=30.000000
x[1][0]=30.000000
x[1][1]=0.000000
x[2][0]=0.000000
x[2][1]=0.000000
x[3][0]=0.000000
x[3][1]=0.000000
x[4][0]=-1.781255
x[4][1]=0.000000
编译时出现警告
warning: left-hand operand of comma expression has no effect [-Wunused-value]
因为
a x = {(40,30),(46,30),(56,30),(58,30),(60,30)};
和
a x = {30, 30, 30, 30, 30};
相同。
你要的是
a x = {{40,30},{46,30},{56,30},{58,30},{60,30}};
(大括号代替圆括号)
或更好
a x = {{40.f,30.f},{46.f,30.f},{56.f,30.f},{58.f,30.f},{60.f,30.f}};
一旦您声明了对象 x,它就像普通的二维数组一样工作。但是,我相信您调用 printf() 的最后一个参数应该传入一个二维数组。因此,而不是:
printf("\nx[%d][%d]=%f",i,j,*x[z++]);
*x[z++] 应该是这样的:
printf("\nx[%d][%d]=%f",i,j,x[i][j]);
您似乎将一个一维数组作为最后一个参数传入。请记住,如果 z 是您声明的变量,则在示例中显示声明非常有价值。
代码有几个问题,但我从最激烈的开始。
数组下标无效
*x[z++]
与 x[z++][0]
相同。假设 z
开头是 0
,您正在访问数组元素 x[0][0]
、x[1][0]
、x[2][0]
、...、x[8][0]
和x[9][0]
。您正在越界访问,因此得到 未定义的行为。打印的最后 5 个值是垃圾。
只需使用语法 x[i][j]
.
错误的数组初始化器
(40,30)
将扩展为 30
,因为您没有使用正确的大括号。代码不违法,但不会给出你想要的结果。您的代码等于:
a x = {{30, 30}, {30, 30}, {30, 0}, {0, 0}, {0, 0}};
正确的初始化器应该是这样的:
a x = {{40.0f, 30.0f}, {46.0f, 30.0f}, {56.0f, 30.0f}, {58.0f, 30.0f}, {60.0f, 30.0f}};
请注意我是如何使用后缀 .0f
来表示这些是浮点数的。这不是绝对必要的,但使用正确的类型是个好习惯。
在 typedef 后面隐藏数组
这不是错误,但将指针或数组隐藏在 typedef
后面并不是一个好习惯。数组在某些情况下表现异常(例如数组衰减为指针),这可能会让程序员感到惊讶。