创建使用C现有的一维数组二维数组? [英] Create 2D array from existing 1D arrays in C?

查看:176
本文介绍了创建使用C现有的一维数组二维数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Perl中我可以创建一维数组,然后从中创建二维数组,方式如下:

  @ A1 =(A,B,C)
@ A2 =(D,E,F)
@ A3 =(G,H,I)
@ m23_v1 =(\\ @ A1 \\ A2 @,\\ @ A3)

下面是另一种方式(假设 @ A1 @ A2 @ A3 相同的previous为例):

  @ m23_v2 =(A1 @],[@ A2],[@ A3])

这两种方式之间的区别是,当反斜杠使用,则改变 $ a [0] [0] 也将改变 $ A1 [ 0] 。在当支架使用,则该值将被复制,以便改变另一方面 $ a [0] [0] 不会改变 $ A1 [0] 。贝娄是变量内存地址应该阐明我的意思是:

 打印\\ $ A1 [0]
标量(0x2006c0a0)打印\\ $ m23_v1 [0] [0]
标量(0x2006c0a0)打印\\ $ m23_v2 [0] [0]
标量(0x2030a7e8)

如何实现相同的,但在C 2我试过以下code:

 #包括LT&;&stdio.h中GT;
诠释主(){
  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]);
}

但它给了我下面的编译警告:

  2d.c:在函数'主':
2d.c:4:3:警告:初始化将指针整数,未作施放[默认启用]
警告::(近初始化为M23 [0] [0]')[默认启用] 2d.c:4:3
2d.c:4:3:警告:初始化将指针整数,未作施放[默认启用]
警告::(近初始化为M23 [0] [1])默认情况下启用] 2d.c:4:3
2d.c:5:3:警告:内建函数'printf的不兼容的隐式声明[默认启用]

执行后按照C code回到

  1
-1077371888

问题:


  1. 为什么我得到的编译警告和如何修改code摆脱他们的?

  2. 如果定的C相当于反斜杠的perl版本,那么什么是支架的版本(反之亦然)等效?

  3. 为什么我得到-1077371888,而不是1?


解决方案

您可以使用指针数组以获得backslahed版本的当量(即 @ m23_v1

 的#include<&stdio.h中GT;INT主要(无效)
{
    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]);    返回0;
}

在您的code:

  INT M23 [2] [3] = {A1,A2};

初​​始化期望填充整数。基本上你创建两个整数二维数组: A1 A2 。剩余的元件被初始化为零。为了说明它,这看起来是这样的:

  INT M23 [2] [3] = {0xaaee33,0xaaee55,0,0,0,0};

这实际上是一样的:

  INT M23 [2] [3] = {{0xaaee33,0xaaee55,0},{0,0,0}}; //两行,三列

然而, A1 不是整数。这是数组的名字,那就是隐含转换为 INT (将其转换为指针后,它指向数组的第一个元素)。换句话说,你是隐含转换的地址A1 A2 成两个整数。事实上,这样的操作是在C和这种code违法甚至不应该与 -pedantic-错误标志(或同等学历)编译。


  

什么是支架的版本(反之亦然)?

相当于

的支撑版本相当于是定义了特定大小的多维数组,然后复制 A1 的每个元素和 A2 阵列进去:

 的#include<&stdio.h中GT;
#包括LT&;&string.h中GT;INT主要(无效)
{
    INT A1 [3] = {1,2,3};
    INT A2 [3] = {4,5,6};    诠释M23 [2] [3];
    的memcpy(M23 + 0,A 1,sizeof的(A1));
    的memcpy(M23 + 1,A2,sizeof的(A2));    的printf(%d个\\ N,A1 [0]);
    的printf(%d个\\ N,M23 [0] [0]);    返回0;
}

In perl I can create 1D arrays and then create 2D array from them, following way:

@a1=(a,b,c)
@a2=(d,e,f)
@a3=(g,h,i)
@m23_v1=(\@a1,\@a2,\@a3)

Here is another way (assuming that @a1, @a2 and @a3 are the same as in previous example):

@m23_v2=([@a1],[@a2],[@a3])

The difference between those two ways is that when backslashes are used then changing $a[0][0] will also change $a1[0]. On the other hand when brackets are used then the value is copied so changing $a[0][0] will not change $a1[0]. Bellow are memory addresses of variables which should clarify what I mean:

print \$a1[0]
SCALAR(0x2006c0a0)

print \$m23_v1[0][0]
SCALAR(0x2006c0a0)

print \$m23_v2[0][0]
SCALAR(0x2030a7e8)

How to achieve the same but in C? I've tried following code:

# 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]);
}

But it gives me following compilation warnings:

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]

After execution the C code returns following:

1
-1077371888

Questions:

  1. Why I get the compilation warnings and how to modify the code to get rid of them?
  2. If given C is equivalent to backslashed perl version then what is the equivalent for brackets version (and vice versa)?
  3. Why I get -1077371888 instead of 1?

解决方案

You can use array of pointers to get an equivalent of backslahed version (i.e. @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;
}

In your code:

int m23[2][3] = {a1, a2};

initializer expects to be filled with integers. Basically you create two-dimensional array with two integers: a1, a2. The remaining elements are initialized with zeros. To illustrate it, this looks something like:

int m23[2][3] = {0xaaee33, 0xaaee55, 0, 0, 0, 0};

which is effectively the same as:

int m23[2][3] = {{0xaaee33, 0xaaee55, 0}, {0, 0, 0}}; // two rows, three columns

However, a1 is not an integer. It's name of array, that is implicitely converted to int (after it is converted into pointer, that points to array's first element). In other words you are implicitely converting addresses of a1 and a2 into two integers. In fact, such operation is illegal in C and such code should not even compile with -pedantic-errors flag (or equivalent).

what is the equivalent for brackets version (and vice versa)?

The equivalent of braced version is define an multidimensional array of specific size and then copy each element of a1 and a2 arrays into it:

#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;
}

这篇关于创建使用C现有的一维数组二维数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆