簡體   English   中英

為什么代碼輸出-1代替1

[英]why does the code output -1 in place of 1

int main ()  
{  
struct bit{  
 char f1:1;  
 char f2:1;  
};  
struct bit b;  
b.f1= 0x1;   
b.f2 = 0x1;   
printf("%d\n",b.f1);  
return 0;  
} 

使用gcc編譯代碼輸出-1。 它應該不是1嗎? 是因為我正在編譯一個小端機器嗎?

補充:使用GDB進行調試時,我看到初始化struct成員后的值為-1。 即打印前它是-1。 以下是GDB的打印輸出:
(gdb)pb
$ 7 = {f1 = -1'',f2 = -1''}

如果您需要更多調試命令,請告訴我。 請提供執行此操作的命令。

char可以是unsigned或者可以是signed類型,由編譯器來決定。 在你的情況下,它顯然是signed所以當你打印你的位字段時,編譯器會將符號擴展到你的位擴展到的int的大小。 在2補碼表示中,不應忘記-1表示為每個位集11111111 11111111 11111111 11111111在32位int上為-1。 如果只有1位,則只能表示2個補碼中的2個值:0和1,它是0和-1的二進制表示。

編輯:這里是C標准第6.2.5節第15節的實際部分:char,signed char和unsigned char這三種類型統稱為字符類型。 實現應將char定義為具有與signed char或unsigned char.35相同的范圍,表示和行為

35)在limits.h中定義的CHAR_MIN將具有值0或SCHAR_MIN之一,這可用於區分這兩個選項。 無論做出何種選擇,char都是與其他兩種類型不同的類型,並且與兩者都不兼容。

您的位域是一位寬並且是有符號值。 最頂部的位通常表示值的符號,因此,將1設置為一位寬的有符號值會設置符號位,以便讀取該值會得到-1。

要添加到Skizz和tristopia的正確答案:對於C99,現代C,位字段應為signedunsigned int類型或bool類型(aka _Bool )。 某些平台可能允許所有其他類型,但不一定是可移植的。 更糟糕的是,即使您將它們指定為plain int ,結果也可能是有符號或無符號的。 因此,如果你只需要一個標志,那么最好堅持使用bool ,當你需要多個位時,可以選擇unsigned

位域通常 應該是 'unsigned xxxxx'。

[編輯]
原因就在於你遇到的情況; 有人以“不尋常”的方式使用位域,得到他們不應該獲得的結果。

位域的要點是反映一點。 有點什么價值? 0和1(我只說正常位,我不能理解量子的東西)。 然而,您已經找到了將-1,0,1插入同一個字段的方法。 在某個地方,它必須打破。 我相信很多位域混淆會導致負位域,因此無符號修飾符可以減輕這種混亂。

將位域定義為int時,可以使用負值。 這就是上述結果的原因。
此外,請參閱此處以獲取有關此主題的更詳細信息。 請注意,這已經在SO上進行了無數次重復,因此搜索“bitfield unsigned”將證明非常有啟發性
[/編輯]

對於'R.',re:“簽名......是實現定義的,但它不能因元素而異。”

#include <stdio.h>
int main ()
{
   struct bit{
      char f1:1;
      unsigned char f2:1;
   };
  struct bit b;
  b.f1 = 1;
  b.f2 = 1;
  printf("%d\n",b.f1);
  printf("%d\n",b.f2);
  return 0;
}

產生,作為輸出:

-1
1

我相信KevinDTimm是正確的 - 位字段通常是unsigned name:x

這就是我認為正在發生的事情:處理器從字段的第一位確定符號。 gcc字符已簽名(有一個unsigned char ,所以你的代碼實際上是:

struct bit 
{
   char f1;
   char f2;
};

每個字符是一個字節(4位),最上面的字節表示符號(1 = neg,0 = pos)。 但是因為你的字段是一位,那就是符號位。 你把它設置為負面。

希望這可以幫助。 如果它是錯的,請評論,以便我可以解決它。

以上解釋很棒。 為了使您的程序正常工作,1個可能的解決方案可能是使得unsigned int類型的位字段。

我不太了解C. 例如,我不知道:1char f1:1做了什么,但我能夠通過刪除以下代碼來使我的PC上運行此代碼:

#include <stdio.h>

int main ()
{
 struct bit{
  char f1;
  char f2;
 };

 struct bit b;

 b.f1 = 0x1;
 b.f2 = 0x1;
 printf("%d\n",b.f1);
 return 0;
}

輸出如下:

chooper@brooklyn:~/test$ gcc -o foo foo.c
chooper@brooklyn:~/test$ ./foo
1

我希望這可以幫助你!

暫無
暫無

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

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