标量初始化多余元素指针型数组 [英] Excess elements of scalar initializer for pointer to array of ints

查看:201
本文介绍了标量初始化多余元素指针型数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作在K&放一个锻炼; R(例5-9),我试图原程序的二维数组转换

 静态字符daytab [2] [13] = {
    {0,31,28,31,30,31,30,31,31,30,31,30,31},
    {0,31,29,31,30,31,30,31,31,30,31,30,31}
};

到使用指针至13整数数组像

 静态CHAR(* daytab)[13] = {
    {0,31,28,31,30,31,30,31,31,30,31,30,31},
    {0,31,29,31,30,31,30,31,31,30,31,30,31}
};

但是编译器打印的警告:在标量初始化多余的元素

谷歌搜索并没有帮助,甚至K&安培; R传递数组时,函数,写

  myFunction的(INT daytab [2] [13]){...}

是相同的

  myFunction的(INT(* daytab)[13]){...}


解决方案

这两个只有部分等价的。不同之处在于:

 静态字符daytab [2] [13] = {
    {0,31,28,31,30,31,30,31,31,30,31,30,31},
    {0,31,29,31,30,31,30,31,31,30,31,30,31}
};

声明了一个两维阵列,包括设置留出空间阵列,并确保 daytab 引用该内存。但是:

 静态CHAR(* daytab)[13] = {
    {0,31,28,31,30,31,30,31,31,30,31,30,31},
    {0,31,29,31,30,31,30,31,31,30,31,30,31}
};

...只是声明了一个指针。所以,你想初始化数组初始化,预期不工作的指针。没有阵列;有没有内存数组备用。会发生什么情况反而是,在你的初始化的第一个数字被分配到指针 daytab ,编译器生成一个警告,让你知道你已经指定了很多附加价值这只是丢弃。由于您的初始化第一个数字是 0 ,你只是设置 daytab NULL 在一个相当冗长的方式。

所以,如果你想要做这种初始化,使用的第一个版本 - 它衰变到同一个指针类型,你明确的第二个版本声明,所以你可以使用同样的方式。第二个版本,与数组指针,是当你想动态分配数组或得到一个已经存在另一个数组引用必要的。

所以,你可以这样做:

 静态炭ARR [2] [3] = {{1,2,3},{4,5,6}};
静态的char(* ptr的)[3] = NULL;PTR = ARR;

...然后使用 PTR 改编互换。或者这样:

 静态CHAR(* PTR)[3] = NULL;PTR =的malloc(2 * sizeof的(* PTR));

...得到一个动态分配的二维阵列(未指针一维数组的数组,但真正的二维数组)。当然,这不是在这种情况下,进行初始化。

在这两个变化的对等只是意味着二维数组,当它衰变为指针,以它的第一要素,衰减到指针在第二个变化声明的类型。一旦指针版本以数组实际上指出,这两者是等价。但二维数组版本设置内存为阵,在指针声明不...和指针可以分配一个新的值(在不同的阵列指向),其中二维数组变量不能。

在C99就可以做到这一点,但(如果不是静态至少):

 字符(* daytab)[13] =(的char [] [13]){
    {0,31,28,31,30,31,30,31,31,30,31,30,31},
    {0,31,29,31,30,31,30,31,31,30,31,30,31}
};

I’m working on an exercise in K&R (ex. 5–9) and I was trying to convert the original program’s 2D array of

static char daytab[2][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

into using pointers to an array of 13 ints like

static char (*daytab)[13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

But compiler prints warning: excess elements in scalar initializer.

Googling did not help and even K&R writes when passing the array to a function,

myFunction(int daytab[2][13]) {...}

is the same as

myFunction(int (*daytab)[13]) {...}

解决方案

The two are only partly equivalent. The difference being that:

static char daytab[2][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

declares a two-dimensional array, which includes setting aside space for the array and ensuring that daytab references that memory. However:

static char (*daytab)[13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

...only declares a pointer. So you're trying to initialize a pointer with an array initializer, which doesn't work as expected. There is no array; there's no memory set aside for an array. What happens instead is that the first number in your initializer is assigned to the pointer daytab, and the compiler generates a warning to let you know you've specified a lot of additional values that are just discarded. Since the first number in your initializer is 0, you're just setting daytab to NULL in a rather verbose way.

So if you want to do this sort of initialization, use the first version -- it decays to the same pointer type that you explicitly declare in the second version, so you can use it the same way. The second version, with the array pointer, is needed when you wish to dynamically allocate the array or get a reference to another array that already exists.

So you can do this:

static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;

ptr = arr;

...and then use ptr and arr interchangeably. Or this:

static char (*ptr)[3] = NULL;

ptr = malloc(2 * sizeof(*ptr));

...to get a dynamically allocated 2-dimensional array (not an array of pointers to 1D arrays, but a real 2D array). Of course, it's not initialized in that case.

The "equivalence" of the two variations just means that the 2D array, when it decays to a pointer to its first element, decays to the type of pointer declared in the second variation. Once the pointer version is actually pointed at an array, the two are equivalent. But the 2D array version sets up memory for the array, where the pointer declaration doesn't... and the pointer can be assigned a new value (pointed at a different array) where the 2D array variable cannot.

In C99 you can do this, though (if not static at least):

char (*daytab)[13] = (char [][13]){
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

这篇关于标量初始化多余元素指针型数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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