簡體   English   中英

對於結構變量,為什么初始化器{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?

在下面的例子中,我用兩個結構test1test2來說明這個。第一個有兩個元素 - 一個大小為2的整數數組,和一個浮點元素。第二個結構有3個元素,2個整數和一個浮點數。

我為test1初始化了兩個結構變量s1s2

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

兩者都工作正常,即使對於s2我已經取出括起數組元素的大括號。它沒有警告工作正常,輸出正確。但是當我為test2初始化2個變量時如下:

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

當我嘗試打印出v1的值時輸出不正確,這些是我在編譯時得到的警告:

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 ===|

基於此前提,請清除以下產生的疑問:

問題:如果使用v1={{23,52},2.5}而不是v1={23,52,2.5}會使編譯器混淆前兩個數字是結構的不同整數元素還是整數數組元素的一部分結構,然后為什么不使用s2={21,19,3.6}而不是s2={{21,19},3.6}混淆編譯器認為結構varialbe s23個元素(2個整數元素和一個float),而不是2個元素(一個大小為2的整數數組和一個浮點數)?我特別想了解的是為什么關於v1初始化的第一個案例是錯誤的。

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

這只是定義初始化程序規則的結果。 如果初始化的當前對象structunion或數組,那么如果下一個初始化程序以{然后由該大括號括起的初始化程序及其匹配}則用於初始化該對象的成員; 否則,它只是通過初始化者列表,盡可能多地使用它。

因此,在第一種情況下, s1={{23,52},2.5} ,當前對象以s1.list 這是一個數組,下一個初始化程序是{ 23, 52 } ,因此用於初始化數組。 s1.rate現在是當前對象,下一個初始化程序是2.5 ,因此可以按預期工作。

在第二種情況下, s2={21,19,3.6} ,當前對象以s2.list 這是一個數組,但是下一個初始化器不會{ - 開頭,因此需要盡可能多的值(在本例中為兩個),並使用2119初始化數組。 s2.rate現在是當前對象,下一個初始化程序是2.5 ,所以再次按預期工作。

在第三種情況下, v1={{23,52},2.5} ,當前對象以v1.list1 這是一個標量,相應的初始值為{23, 52} 這違反了語言的約束 - “標量的初始值設定項應該是單個表達式,可選地用括號括起來 ” - 這就是為什么你會收到警告的原因。 正式地,程序的行為是未定義的,但看起來您的編譯器只使用初始化程序中包含的第一個值並丟棄多余的程序。 當前對象現在是v1.list2 ,下一個初始化程序是2.5 ,因此使用錯誤的值初始化此成員。 v1.rate沒有初始化v1.rate ; 由於v1具有靜態存儲持續時間,因此該成員的初始化為0.0

v2={21,19,3.6}情況下, v2={21,19,3.6} ,當前對象以v1.list1 ,下一個初始化為21 - 該值用於初始化成員。 在此之后,當前對象是v1.list2 ,下一個初始化器是19 ; 然后v1.rate是當前對象,下一個初始化程序是3.6

為了最小化混淆,您應該始終為每個struct或數組子對象使用括號括起的初始化程序。

在變量s2的情況下,編譯器知道嵌入式數組的大小,因此即使沒有括號,它也可以正確地分配給它。 然而,您可能會收到一條警告,建議您使用護腕,如果不這樣做,我建議您啟用更多編譯器警告(最好修復警告,因為它們可能表示可能是有效C但無效邏輯的錯誤)。

v1的情況下,您不能使用額外的支撐,因為沒有復合數據類型(結構/聯合/數組)。 括號{}只能用於初始化復合數據類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM