对于结构变量,为什么初始化{} 21,19,3.6一样{{} 21,19,3.6},而不是相反? [英] For a structure variable,why is the initializer {21,19,3.6} same as {{21,19},3.6},but not vice-versa?

查看:226
本文介绍了对于结构变量,为什么初始化{} 21,19,3.6一样{{} 21,19,3.6},而不是相反?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的例子中,我已经说明了这个使用两种结构测试1 测试2 。首先有两个元素 - 一个整数数组大小两个,一个浮动element.The第二个结构有3个要素,2个整数和一个浮动。

我初始化二元结构变量 S1 S2 对于测试1 为:

  S1 = {{23,52}} 2.5,S2 = {} 21,19,3.6;

都工作得不错,即使对于 S2 我已经采取了来括起数组elements.It工作正常,没有警告和输出大括号是correct.But当我初始化2变量的 TEST2 如下:

  V1 = {{23,52}} 2.5,V2 = {} 21,19,3.6;

我得到不正确的输出,当我尝试打印出来的值 V1 并这些都是我在编译时得到了警告:

 警告:标量初始化括号|
警告:(近初始化v1.list1')|
警告:在标量初始化多余的元素|
警告:(近初始化v1.list1')|
|| ===构建完成:0错误,警告4 === |

在此基础上premise,请清除产生以下疑问:

问:如果使用 V1 = {{23,52},2.5} 而不是 V1 = {的23 ,52,2.5} 混淆关于第2号是否是结构的整数数组元素的结构或部分不同的整数元素,那么为什么不使用 S2 = {21,19,3.6} 而不是 S2 = {{21,19},3.6} 混淆编译器误以为结构varialbe S2 3 元素(2整型元素和一个浮动),而不是 2 元素(大小为2的一个整数数组和一个浮动)?我特别想了解的是,为什么是关于第一种情况下的 V1 的初始化错误的。

 #包括LT&;&stdio.h中GT;结构TEST1 {
INT名单[2];
浮动利率;
} S1 = {{23,52}} 2.5,S2 = {} 21,19,3.6; //工作正常结构测试2 {
INT list1的;
INT列表2;
浮动利率;
} V1 = {{23,52}} 2.5,V2 = {} 21,19,3.6; //食堂的东西了INT主要(无效)
{
    的printf(%D,%D,%F \\ N,s1.list [1],s2.list [1],s2.rate);
    的printf(%D,%D,%F \\ N,v1.list1,v1.list2,v1.rate);
}


解决方案

这只是一个如何为initialisers规则定义的后果。如果的当前对象的初始化是一个结构联盟或数组,那么如果接下来的初始化器均以 {然后由括号及其配套包围的initialisers } 用于初始化成员该对象的;否则,它只是通过initialisers列表进军,以尽可能多的,因为它需要的。

所以,在第一种情况下 S1 = {{23,52},2.5} ,当前的对象开始作为 s1.list 。这是一个数组,并且下一个初始化剂是 {23,52} ,所以这是用于初始化所述阵列。 s1.rate 现在当前对象,接下来的初始化器是 2.5 ,以便按预期工作。

在第二种情况下 S2 = {21,19,3.6} ,当前的对象开始作为 s2.list 。这是一个数组,但接下来的初始化器做的的开始了以 { - 所以,因为它需要(在这种情况下,它需要尽可能多的价值,二),并与初始化数组 21 19 s2.rate 现在当前对象,接下来的初始化器是 2.5 ,如此反复的正常工作。

在第三种情况下 V1 = {{23,52},2.5} ,当前的对象开始作为 v1.list1 。这是一个标量,以及相应的初始化器是 {23,52} 。这违反了语言的限制 - 的的标量的初始化应该是单个前pression,可选括在大括号的 - 所以这就是为什么你会得到一个警告。正式程序的行为是不确定的,但现在看来,你的编译器只是使用包含在初始化器的第一个值,并丢弃多余的。现在当前对象是 v1.list2 ,接下来的初始化器是 2.5 ,所以使用了错误的值初始化此成员。没有初始化器为 v1.rate ;因为 V1 具有静态存储持续时间,该成员初始化器到 0.0

在第四的情况下 V2 = {21,19,3.6} ,当前的对象开始作为 v1.list1 ,接下来的初始化器是 21 - 这个值是用来初始化成员。在此之后,当前的目标是 v1.list2 和下一个初始化器是 19 ;那么 v1.rate 是当前对象和下一个初始化器是 3.6

有关最低混乱,你应该总是每件都用括号括起来的初始化器结构或数组子对象。

In the following example,I've illustrated this using two structures test1 and test2.The first has two elements-an integer array sized two,and a float element.The second structure has 3 elements,2 integers and one float.

I initialize two structure variables s1 and s2 for test1 as:

s1={{23,52},2.5},s2={21,19,3.6};

Both work fine even though for s2 I have taken out the braces that enclose the array elements.It works fine without warning and output is correct.But when I initialize 2 variables for test2 as follows:

 v1={{23,52},2.5},v2={21,19,3.6};

I get incorrect output when I try to print out values of v1 and these are the warnings that I had got upon compilation:

warning: braces around scalar initializer|
warning: (near initialization for 'v1.list1')|
warning: excess elements in scalar initializer|
warning: (near initialization for 'v1.list1')|
||=== Build finished: 0 errors, 4 warnings ===|

Based on this premise,please clear the following doubt that arise:

Question: If using v1={{23,52},2.5} instead of v1={23,52,2.5} confuses the compiler about whether the first 2 numbers are distinct integer elements of the structure or part of an integer array element of the structure,then why doesn't using s2={21,19,3.6} instead of s2={{21,19},3.6} confuse the compiler into thinking that the structure varialbe s2 has 3 elements (2 integer elements and one float),instead of 2 elements (one integer array of size 2 and a float)?What I especially want to understand is why is the first case about v1's initialization wrong.

#include<stdio.h>

struct test1{
int list[2];
float rate;
}s1={{23,52},2.5},s2={21,19,3.6}; //Works fine

struct test2{
int list1;
int list2;
float rate;
}v1={{23,52},2.5},v2={21,19,3.6};  //Messes things up

int main(void)
{
    printf("%d,%d,%f\n",s1.list[1],s2.list[1],s2.rate);
    printf("%d,%d,%f\n",v1.list1,v1.list2,v1.rate);
}

解决方案

This is just a consequence of how the rules for initialisers are defined. If the current object of the initialisation is a struct, union or array, then if the next initialiser begins with a { then the initialisers enclosed by that brace and its matching } are used to initialise the members of that object; otherwise, it just marches through the list of initialisers, taking as many as it needs.

So, in the first case s1={{23,52},2.5}, the current object starts out as s1.list. This is an array, and the next initialiser is { 23, 52 }, so that's used to initialise the array. s1.rate is now the current object, and the next initialiser is 2.5, so that works as expected.

In the second case s2={21,19,3.6}, the current object starts out as s2.list. This is an array, but the next initialiser does not start out with { - so it takes as many values as it needs (in this case, two), and initialises the array with 21 and 19. s2.rate is now the current object, and the next initialiser is 2.5, so again that works as expected.

In the third case v1={{23,52},2.5}, the current object starts out as v1.list1. This is a scalar, and the corresponding initialiser is {23, 52}. This violates a constraint of the language - "The initializer for a scalar shall be a single expression, optionally enclosed in braces" - so that's why you get a warning. Formally the behaviour of your program is undefined, but it appears that your compiler just uses the first value contained in the initialiser and discards the excess ones. The current object is now v1.list2, and the next initialiser is 2.5, so the wrong value is used to initialise this member. There is no initialiser for v1.rate; since v1 has static storage duration, this member is initialiser to 0.0.

In the forth case v2={21,19,3.6}, the current object starts out as v1.list1, and the next initialiser is 21 - this value is used to initialise the member. After this the current object is v1.list2 and the next initialiser is 19; then v1.rate is the current object and the next initialiser is 3.6.

For minimum confusion, you should always use a brace-enclosed initialiser for each struct or array subobject.

这篇关于对于结构变量,为什么初始化{} 21,19,3.6一样{{} 21,19,3.6},而不是相反?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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