我一直在看這段代碼。我知道輸出是50,但我不確定這是怎麼發生的。不確定輸出是如何得到的!位字段
struct
{
unsigned m : 3;
unsigned n : 5;
} b;
int main(void)
{
b.m = 2;
b.n = 6;
printf("%d", b);
}
任何幫助別人可以提供,我真的很感激。
我一直在看這段代碼。我知道輸出是50,但我不確定這是怎麼發生的。不確定輸出是如何得到的!位字段
struct
{
unsigned m : 3;
unsigned n : 5;
} b;
int main(void)
{
b.m = 2;
b.n = 6;
printf("%d", b);
}
任何幫助別人可以提供,我真的很感激。
嗯,似乎與位域連續的一個結構被壓縮,而傳遞給printf
與%d
格式說明時,這體現像是某種「位聚合」(見注)。一些測試與不同的價值觀和這樣的,我想出了以下方案:
的結構成員(位域)的排列正是如此:
n n n n n m m m
即「降」命令 - 去年是第一位的。
然後,在main
,BM得到值2,其在二進制是10和在3位格式是010,和BN得到值6,其在二進制爲110,並在5位格式是00110,所以你最終00110010具有的價值十二月50.
爲了進一步檢驗這個假設我擴大了與一個成員的b結構,並檢查它是否仍然成立:
#include <stdio.h>
struct {
unsigned m : 3;
unsigned n : 5;
unsigned o : 5;
} b;
int main(void) {
b.m = 1;
b.n = 1;
b.o = 1;
printf("%d\n",b);
return 0;
}
根據該假設的結構成員應該對齊這樣:
o o o o o n n n n n m m m
並用二進制0000100001001在main
分配給它們的值(即1,1和1)這將導致其在分解是265.
編譯和運行率:
$ gcc -Wall -o stprint stprint.c
stprint.c: In function ‘main’:
stprint.c:13:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘struct <anonymous>’ [-Wformat=]
printf("%d\n",b);
^
$ ./stprint
265
即結果是(最有可能)驗證的假說。 希望我對這種行爲有所瞭解。
編輯/注:如果它不是來自上面的清晰,其他批評家指出,這種行爲依賴於實現,這意味着它是由編譯器來決定,如果這個「位聚合「發生與否,具體順序是什麼。人們還需要考慮底層平臺的字節順序(例如,參見here)。對於這篇文章,在Ubuntu系統中使用了gcc version 4.8.4
。
這調用**未定義的行爲** - 任何事情都可能發生。 –
那就是我在想什麼。這是一個考試的練習題,我明顯應該做些什麼。我只能回答輸出 – guy25
好的,但要記住練習文件是錯誤的,然後(除非預期的答案是「未定義的行爲」......) –