在 perl 中,我可以创建一维数组,然后从它们创建二维数组,如下所示:
@a1=(a,b,c)
@a2=(d,e,f)
@a3=(g,h,i)
@m23_v1=(\@a1,\@a2,\@a3)
Run Code Online (Sandbox Code Playgroud)
这是另一种方式(假设@a1、@a2和@a3与前面的示例相同):
@m23_v2=([@a1],[@a2],[@a3])
Run Code Online (Sandbox Code Playgroud)
这两种方式之间的区别在于,当使用反斜杠时,更改$a[0][0]也会更改$a1[0]。另一方面,当使用括号时,值将被复制,因此更改$a[0][0]不会更改$a1[0]。波纹管是变量的内存地址,它们应该阐明我的意思:
print \$a1[0]
SCALAR(0x2006c0a0)
print \$m23_v1[0][0]
SCALAR(0x2006c0a0)
print \$m23_v2[0][0]
SCALAR(0x2030a7e8)
Run Code Online (Sandbox Code Playgroud)
如何在 C 中实现相同的功能?我试过以下代码:
# include <stdio.h>
int main(){
int a1[3] = {1,2,3};
int a2[3] = {4,5,6};
int m23[2][3] = {a1, a2};
printf("%d\n", a1[0]);
printf("%d\n", m23[0][0]);
}
Run Code Online (Sandbox Code Playgroud)
但它给了我以下编译警告:
2d.c: In function ‘main’:
2d.c:4:3: warning: initialization makes integer from pointer without a cast [enabled by default]
2d.c:4:3: warning: (near initialization for ‘m23[0][0]’) [enabled by default]
2d.c:4:3: warning: initialization makes integer from pointer without a cast [enabled by default]
2d.c:4:3: warning: (near initialization for ‘m23[0][1]’) [enabled by default]
2d.c:5:3: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
Run Code Online (Sandbox Code Playgroud)
执行后,C 代码返回以下内容:
1
-1077371888
Run Code Online (Sandbox Code Playgroud)
问题:
您可以使用指针数组来获得等效的反斜线版本(即@m23_v1):
#include <stdio.h>
int main(void)
{
int a1[3] = {1,2,3};
int a2[3] = {4,5,6};
int *m23[2] = {a1, a2};
printf("%d\n", a1[0]);
printf("%d\n", m23[0][0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在你的代码中:
int m23[2][3] = {a1, a2};
Run Code Online (Sandbox Code Playgroud)
初始化器期望用整数填充。基本上你用两个整数创建二维数组:a1,a2。其余元素用零初始化。为了说明这一点,这看起来像:
int m23[2][3] = {0xaaee33, 0xaaee55, 0, 0, 0, 0};
Run Code Online (Sandbox Code Playgroud)
这实际上等同于:
int m23[2][3] = {{0xaaee33, 0xaaee55, 0}, {0, 0, 0}}; // two rows, three columns
Run Code Online (Sandbox Code Playgroud)
但是,a1不是整数。它是数组的名称,隐式转换为int(转换为指针后,指向数组的第一个元素)。换句话说,您正在隐式转换a1和的地址a2的地址隐式转换为两个整数。事实上,这样的操作在 C 中是非法的,这样的代码甚至不应该使用-pedantic-errors标志(或等效的)进行编译。
括号版本的等效项是什么(反之亦然)?
花括号版本的等效项是定义一个特定大小的多维数组,然后将a1和a2数组的每个元素复制到其中:
#include <stdio.h>
#include <string.h>
int main(void)
{
int a1[3] = {1,2,3};
int a2[3] = {4,5,6};
int m23[2][3];
memcpy(m23 + 0, a1, sizeof(a1));
memcpy(m23 + 1, a2, sizeof(a2));
printf("%d\n", a1[0]);
printf("%d\n", m23[0][0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)