1. 程式人生 > >C語言變數宣告加冒號的用法 稱為“位域”或“位段“

C語言變數宣告加冒號的用法 稱為“位域”或“位段“

 有些資訊在儲存時,並不需要佔用一個完整的位元組, 而只需佔幾個或一個二進位制位。例如在存放一個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省儲存空間,並使處理簡便,C語言又提供了一種資料結構,稱為“位域”或“位段”。所謂“位域”是把一個位元組中的二進位劃分為幾 個不同的區域,並說明每個區域的位數。每個域有一個域名,允許在程式中按域名進行操作。這樣就可以把幾個不同的物件用一個位元組的二進位制位域來表示。一、位 域的定義和位域變數的說明位域定義與結構定義相仿,其形式為:

struct 位域結構名
{ 位域列表 };

其中位域列表的形式為: 型別說明符 位域名:位域長度

例如:

struct bs
{
int a:8;
int b:2;
int c:6;
};


位域變數的說明與結構變數說明的方式相同。 可採用先定義後說明,同時定義說明或者直接說明這三種方式。例如:

struct bs
{
int a:8;
int b:2;
int c:6;
}data;

說明data為bs變數,共佔兩個位元組。其中位域a佔8位,位域b佔2位,位域c佔6位。對於位域的定義尚有以下幾點說明:

1. 一個位域必須儲存在同一個位元組中,不能跨兩個位元組。如一個位元組所剩空間不夠存放另一位域時,應從下一單元起存放該位域。也可以有意使某位域從下一單元開始。例如:

struct bs
{
unsigned a:4
unsigned :0
unsigned b:4
unsigned c:4
}

在這個位域定義中,a佔第一位元組的4位,後4位填0表示不使用,b從第二位元組開始,佔用4位,c佔用4位。

2. 位域可以無位域名,這時它只用來作填充或調整位置。無名的位域是不能使用的。例如:

struct k
{
int a:1
int :2
int b:3
int c:2
};

從以上分析可以看出,位域在本質上就是一種結構型別, 不過其成員是按二進位分配的。

又:

1:指標型別變數不能指定所佔的位數
2. 在宣告成員變數時,可以用 變數名 :bit數;
來確定結構體型別的成員變數的值所佔的字位數,如果在實際應用中,該變數的值超出了在宣告它時所宣告的字位數,那麼溢位的部分將會丟失。

例子:

#include
#include

using namespace std;

struct BitVariable {
unsigned a:2;
unsigned b:3;
unsigned :0;
unsigned c:6;


} BitVariable1;

int main(int argc, char *argv[])
{
BitVariable BV1;
BV1.a=2; //10
BV1.b=8; //1000
BV1.c=86; //1010110

cout<<BV1.a<<endl; //output 2 <===> 10B
cout<<BV1.b<<endl; //output 0 <===> 1000B
cout<<BV1.c<<endl; //output 22 <===> 10110B
cout<<sizeof(BitVariable)<<endl; //output 8. int 32位機器佔4位元組。 如果將unsigned :0;去掉,則此處輸出4。

system("PAUSE");
return EXIT_SUCCESS;
}

struct對齊:詳解結構體、類等記憶體位元組對齊

一、WINDOWS下(VC--其實GCC和其原理基本一樣,象這種問題,一般要查具體的編譯器設定)位元組對齊的規則:

1、一般設定的對齊方式為1,2,4位元組對齊方式,VC一般預設為4位元組(最大為8位元組)。結構的首地址必須是結構內最寬型別的整數倍地址;另外,結構體的每一個成員起始地址必須是自身型別大小的整數倍(需要特別注意的是windows下是這樣的,但在linux的gcc編譯器下最高為4位元組對齊),否則在前一型別後補0;這裡特別提到的是陣列一定要注意,而且在一些程式設計的技巧中,我們可以使用陣列強制位元組達到對齊的目的。這在網路程式設計中是很常見的。

舉例:比如CHAR型佔用空間為1位元組,則其起始位置必須可被1整除。INT為4位元組,其起始位置必須被4帶隊,依次類推。(我們假定類或結構體的起始位置為0位置,其實編譯器是在開闢空間時,會尋找起始位置可被結構內最寬型別整除的地址做為開始地址,因此我們可以假定其為0值,因為這0值可以被任意的型別整除。)

2、結構體的整體大小必須可被對齊值整除,預設4(預設,且結構中的型別大小都小於預設的4)。

3、結構體的整體大小必須可被本結構內的最寬型別整除。(其實和上一條是一樣的,但這裡獨立出來,起注意作用。比如結構體裡的有DOUBLE,那麼結構的大小最後必須可被8整除)

注意:GCC不是這樣,就是最高只能被4整除,它是個死的。

否則(2、3條),編譯器會在結構的最後添充一定的特定字元來補齊。

struct T
{
char ch;
double d ;
};

在VC中是16個位元組,GCC中為12個位元組。

4、對於結構體內巢狀結構體的形勢,規定是必須按照基本資料型別來定義,而不能以巢狀結構大小來做為上三種使用的基準。

二、舉例:

struct A
{
int a;
char b;
short c;
};
struct B
{
char b;
int a;
short c;
};
struct C
{
double t;
char b;
int a;
short c;
};
struct D
{
char b;
double t;
int a;
short c;
};

在VC中,SIZEOF這四個結構體,分別為:8、12、24、24;

我們先談第一個,(說明一下,在考慮結構體大小時,我們基本可以忽略起始地址的問題,因為這個編譯器會自動為我們做好,見上面的說明),結構體內首先是一個INT的4位元組,起始地址假定為0,整除4,其小於等於預設的4位元組對齊且0為4(INT的佔用空間)的整數倍,所以,其佔四個位元組;其後為起始地址為5,空間為1個位元組的CHAR,小於4且5為1(CHAR佔用空間)的整數倍,故佔用1個位元組,然後是一個起始地址為5佔2個位元組的SHORT,其小於4,但5不為2位數,故補齊一個位元組,從第6個位元組開始,佔2位元組空間。所以共佔用4+1+1(補)+2=8;8/4=2;整除,故佔用8位元組空間。

再談第2個,CHAR不用解釋,佔有一個位元組空間,且可以被0地址整除。而INT則佔4位元組空間,所以其必須在CHAR後補齊3位元組,到第四個位元組,才是INT的真正地址。SHORT也不用說,所以共佔有:1+3(補)+4+2=10個位元組,但10不能整除4,所以要在結構體最後補齊2位元組。故實際佔有10+2= 12個位元組。

談第三個,C結構體只是在B結構體前加了一個DOUBLE,其它都一樣,按說應該是20個位元組啊,但注意我們上面規則的第3條。必須是最寬型別的整數倍,一定要分清,所以得補齊到24,D結構體類似,不再講。

三、結構體的中含有位域

這個東西用得比較少,但還是總結一下:

如果結構體中含有位域(bit-field),那麼VC中準則又要有所更改:
1) 如果相鄰位域欄位的型別相同,且其位寬之和小於型別的sizeof大小,則後面的欄位將緊鄰前一個欄位儲存,直到不能容納為止;
2) 如果相鄰位域欄位的型別相同,但其位寬之和大於型別的sizeof大小,則後面的欄位將從新的儲存單元開始,其偏移量為其型別大小的整數倍;
3) 如果相鄰的位域欄位的型別不同,則各編譯器的具體實現有差異,VC6採取不壓縮方式(不同位域欄位存放在不同的位域型別位元組中),Dev-C++和GCC都採取壓縮方式;
備註:當兩欄位型別不一樣的時候,對於不壓縮方式,例如:

struct N
{
char c:2;
int i:4;
};

依然要滿足不含位域結構體記憶體對齊準則第2條,i成員相對於結構體首地址的偏移應該是4的整數倍,所以c成員後要填充3個位元組,然後再開闢4個位元組的空間作為int型,其中4位用來存放i,所以上面結構體在VC中所佔空間為8個位元組;而對於採用壓縮方式的編譯器來說,遵循不含位域結構體記憶體對齊準則第2條,不同的是,如果填充的3個位元組能容納後面成員的位,則壓縮到填充位元組中,不能容納,則要單獨開闢空間,所以上面結構體N在GCC或者Dev-C++中所佔空間應該是4個位元組。

4) 如果位域欄位之間穿插著非位域欄位,則不進行壓縮;
備註:
結構

typedef struct
{
char c:2;
double i;
int c2:4;
}N3;

在GCC下佔據的空間為16位元組,在VC下佔據的空間應該是24個位元組。

四、位元組對齊的控制方法

主要是使用:

#pragma pack (2)
struct C
{
char b;
int a;
short c;
};
#pragma pack ()

大家如果有興趣,可以自己上機調一下各種對齊方式下的佔用空間大小,這裡就不再舉例。

#pragma pack(push) //儲存對齊狀態
#pragma pack(4)//設定為4位元組對齊
struct test
{
char m1;
double m4;
int m3;
};
#pragma pack(pop)//恢復對齊狀態

這裡需要注意的是,如果對齊的位元組非為1、2、4、8等可整除位數,則自動預設回預設的對齊位元組數,這個我沒有測試,大家可以試一下,應該沒什麼問題。

五、多編譯器的使用:(其下為轉載

為了防止不同編譯器對齊不一樣,建議在程式碼裡面指定對齊引數

可能重要的一點是關於緊縮結構的。緊縮結構的用途 其實最常用的結構對齊選項就是:預設對齊和緊縮。在兩個程式,或者兩個平臺之間傳遞資料時,我們通常會將資料結構設定為緊縮的。這樣不僅可以減小通訊量,還可以避免對齊帶來的麻煩。假設甲乙雙方進行跨平臺通訊,甲方使用了“/Zp2”這麼奇怪的對齊選項,而乙方的編譯器不支援這種對齊方式,那麼乙方就可以理解什麼叫欲哭無淚了。 當我們需要一個位元組一個位元組訪問結構資料時,我們通常都會希望結構是緊縮的,這樣就不必考慮哪個位元組是填充位元組了。我們把資料儲存到非易失裝置時,通常也會採用緊縮結構,既減小儲存量,也方便其它程式讀出。各編譯器都支援結構的緊縮,即連續排列結構的各成員變數,各成員變數之間沒有任何填充位元組。這時,結構的大小等於各成員變數大小的和。緊縮結構的變數可以放在1n邊界,即任意地址邊界。在GNU gcc:

typedef struct St2Tag

{

St1 st1;

char ch2;

}

__attribute__ ((packed)) St2;

在ARMCC:

typedef __packed struct St2Tag

{

St1 st1;

char ch2;

} St2;

在VC:

#pragma pack(1)

typedef struct St2Tag

{

St1 st1;

char ch2;

} St2;

#pragma pack()

針對不同的編譯器:

#ifdef __GNUC__

#define GNUC_PACKED __attribute__ ((packed))

#else

#define GNUC_PACKED

#endif

#ifdef __arm

#define ARM_PACKED __packed

#else

#define ARM_PACKED

#endif

#ifdef WIN32

#pragma pack(1)

#endif

typedef ARM_PACKED struct St2Tag

{

St1 st1;

char ch2;

}

GNUC_PACKED St2;

#ifdef WIN32

#pragma pack()

#endif

最後記錄一個小細節。gcc編譯器和VC編譯器都支援在緊縮結構中包含非緊縮結構,例如前面例子中的St2可以包含非緊縮的St1。但對於ARM編譯器而言,緊縮結構包含的其它結構必須是緊縮的。如果緊縮的St2包含了非緊縮的St1,編譯時就會報錯

C編譯器的預設位元組對齊方式(自然對界)

在預設情況下,C編譯器為每一個變數或是資料單元按其自然對界條件分配空間。

在結構中,編譯器為結構的每個成員按其自然對界(alignment)條件分配空間。各個成員按照它們被宣告的順序在記憶體中順序儲存(成員之間可能有插入的空位元組),第一個成員的地址和整個結構的地址相同。

C編譯器預設的結構成員自然對界條件為“N位元組對齊”,N即該成員資料型別的長度。如int型成員的自然對界條件為4位元組對齊,而double型別的結構成員的自然對界條件為8位元組對齊。若該成員的起始偏移不位於該成員的“預設自然對界條件”上,則在前一個節面後面新增適當個數的空位元組。

C編譯器預設的結構整體的自然對界條件為:該結構所有成員中要求的最大自然對界條件。若結構體各成員長度之和不為“結構整體自然對界條件的整數倍,則在最後一個成員後填充空位元組。

例子1(分析結構各成員的預設位元組對界條界條件和結構整體的預設位元組對界條件):

struct Test
{ 
char x1; // 成員x1為char型(其起始地址必須1位元組對界),其偏移地址為0 

char x2; // 成員x2為char型(其起始地址必須1位元組對界,其偏移地址為1 

float x3; // 成員x3為float型(其起始地址必須4位元組對界),編譯器在x2和x3之間填充了兩個空位元組,其偏移地址為4 

char x4; // 成員x4為char型(其起始地址必須1位元組對界),其偏移地址為8 
}; 

因為Test結構體中,最大的成員為flaot x3,因些此結構體的自然對界條件為4位元組對齊。則結構體長度就為12位元組,記憶體佈局為1100 1111 1000。

例子2:

#include 
//#pragma pack(2)
typedef struct
{
int aa1; //4個位元組對齊 1111
char bb1;//1個位元組對齊 1
short cc1;//2個位元組對齊 011
char dd1; //1個位元組對齊 1
} testlength1;
int length1 = sizeof(testlength1); //4個位元組對齊,佔用位元組1111 1011 1000,length = 12

typedef struct
{
char bb2;//1個位元組對齊 1
int aa2; //4個位元組對齊 01111
short cc2;//2個位元組對齊 11
char dd2; //1個位元組對齊 1
} testlength2;
int length2 = sizeof(testlength2); //4個位元組對齊,佔用位元組1011 1111 1000,length = 12


typedef struct
{
char bb3; //1個位元組對齊 1
char dd3; //1個位元組對齊 1
int aa3; //4個位元組對齊 001111
short cc23//2個位元組對齊 11

} testlength3;
int length3 = sizeof(testlength3); //4個位元組對齊,佔用位元組1100 1111 1100,length = 12


typedef struct
{
char bb4; //1個位元組對齊 1
char dd4; //1個位元組對齊 1
short cc4;//2個位元組對齊 11
int aa4; //4個位元組對齊 1111
} testlength4;
int length4 = sizeof(testlength4); //4個位元組對齊,佔用位元組1111 1111,length = 8


int main(void)
{
printf("length1 = %d.\n",length1);
printf("length2 = %d.\n",length2);
printf("length3 = %d.\n",length3);
printf("length4 = %d.\n",length4);
return 0;
}

改變預設的對界條件(指定對界)
· 使用偽指令#pragma pack (n),C編譯器將按照n個位元組對齊。
· 使用偽指令#pragma pack (),取消自定義位元組對齊方式。

這時,對齊規則為:

1、資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第一個資料成員放在offset為0的地方,以後每個資料成員的對齊按照#pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。

2、結構(或聯合)的整體對齊規則:在資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。

結合1、2推斷:當#pragma pack的n值等於或超過所有資料成員長度的時候,這個n值的大小將不產生任何效果。

因此,當使用偽指令#pragma pack (2)時,Test結構體的大小為8,記憶體佈局為11 11 11 10。

需要注意一點,當結構體中包含一個子結構體時,子結構中的成員按照#pragma pack指定的數值和子結構最大資料成員長度中,比較小的那個進行進行對齊。例子如下:

#pragma pack(8)
struct s1{
short a;
long b;
};

struct s2{
char c;
s1 d;
long long e;
};
#pragma pack()

sizeof(s2)的結果為24。S1的記憶體佈局為1100 1111,S2的記憶體佈局為1000 1100 1111 0000 1111 1111。

例子:

#include 
#pragma pack(2)
typedef struct
{
int aa1; //2個位元組對齊 1111
char bb1;//1個位元組對齊 1
short cc1;//2個位元組對齊 011
char dd1; //1個位元組對齊 1
} testlength1;
int length1 = sizeof(testlength1); //2個位元組對齊,佔用位元組11 11 10 11 10,length = 10

typedef struct
{
char bb2;//1個位元組對齊 1
int aa2; //2個位元組對齊 01111
short cc2;//2個位元組對齊 11
char dd2; //1個位元組對齊 1
} testlength2;
int length2 = sizeof(testlength2); //2個位元組對齊,佔用位元組10 11 11 11 10,length = 10


typedef struct
{
char bb3; //1個位元組對齊 1
char dd3; //1個位元組對齊 1
int aa3; //2個位元組對齊 11 11
short cc23//2個位元組對齊 11

} testlength3;
int length3 = sizeof(testlength3); //2個位元組對齊,佔用位元組11 11 11 11,length = 8


typedef struct
{
char bb4; //1個位元組對齊 1
char dd4; //1個位元組對齊 1
short cc4;//2個位元組對齊 11
int aa4; //2個位元組對齊 11 11
} testlength4;
int length4 = sizeof(testlength4); //2個位元組對齊,佔用位元組11 11 11 11,length = 8


int main(void)
{
printf("length1 = %d.\n",length1);
printf("length2 = %d.\n",length2);
printf("length3 = %d.\n",length3);
printf("length4 = %d.\n",length4);
return 0;
}

另外,還有如下的一種方式:

· __attribute((aligned (n))),讓所作用的結構成員對齊在n位元組自然邊界上。如果結構中有成員的長度大於n,則按照最大成員的長度來對齊。

· __attribute__ ((packed)),取消結構在編譯過程中的優化對齊,按照實際佔用位元組數進行對齊。

以上的n = 1, 2, 4, 8, 16... 第一種方式較為常見。

一個問題: bit field的對齊問題

為了降低memory的使用量,有些struct中會使用bit field,但是bit field開始地址必須進行對齊,比如下面是一個例子:

struct example {

 char  a;

 char  b;

 char c;

 char d;

 short e;

 int  f : 7;

 int  g : 9;

 int  h:  10;

 int  i:  6

 short  j;

 int  k;

}

在上面這個例子中可以看到,因為int使用了bit field,因此編譯器不能自動進行int對齊,而是會變成:

struct example {

 char  a;

 char  b;

 char c;

 char d;

 short e;   //32 bit的開始, e/f/g組成了一個int

 int  f : 7;

 int  g : 9;   

 int  h:  10;

 int  i:  6

 short  j;

 int   k;

}

這會導致儲存出現問題。因此在bit field之前必須進行手工的對齊:

struct example {

 char  a;

 char  b;

 char c;

 char d;

 short e;   //32 bit的開始, e/reserver組成了一個int

 short reserver; 

int  f : 7;   //現在bit field開始的int是32bit對齊的地址了

 int  g : 9;   

 int  h:  10;

 int  i:  6

 short  j;

 int   k;

}

通過手工插入了一個short的變數,使得bit field現在的開始地址是對齊的了。

可見: 如果使用了bit field,編譯器不能進行自動的地址對齊,而是必須進行手工對齊。

下面是網上關於bit field對齊的一些文章:

struct A {
int a:8;
int b:16;
int c:31;
int d:8;
int e:9;
};

的物件的記憶體情況應該是(a b p) (c p) (d e p),共 4bytes*3 = 12bytes(32bit機器,xp, gcc3.3, vc6驗證過)。

想找個bit-field的對齊啊分配啊什麼的規則,看了半天,沒有找到像對齊規則那樣適用於bit-field的描述,哭。下面是些結果:

先跑去看C99,只發現下面幾個有用的描述,大概說bit-field不在是int這樣的型別,而是一個獨立的概念,分配時不按照對其規則在int(或者其他的型別)的邊界上對齊,而應該連續地被分配。具體怎麼在一個可定址儲存單元內對齊是unspecified behavior。

6.7.2.1
10
An implementation may allocate any addressable storage unit large enought to hold a bit-field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.
11
A bit-field declaration with no declarator, but only a colon and a width, indicates an unnamed bit-field. (Notes: An unnamed bit-field structure memeber is useful for padding to conform to externally imposed layouts.) As a special case, a bit-field structure member with a width of 0 indicates that no further bit-field is to be packed into the unit in which the previous bit-field, if any, was placed.
Annex J
J.1 Unspecified behavior
- The alignment of the addressable storage unit allocated to hold a bit-field.
另外,標準說int,包括unsigned和signed,以及_Bool是標準支援的bit-field,在
J.5 Common extensions
J.5.8 Extended bit-field types
中說可以擴充套件到其他的型別,所以gcc中有對char,short等型別的bit-field的支援。

再跑去看gcc的手冊,在
http://gcc.gnu.org/onlinedocs/
查到gcc相關版本的reference manual,比如:
http://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/
找bit-field,在
http://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html#Structures-unions-enumerations-and-bit_002dfields-implementation
發現所有gcc的實現都是引用C99規範中的相關說明 - -
Whether a “plain” int bit-field is treated as a signed int bit-field or as an unsigned int bit-field (6.7.2, 6.7.2.1).
Allowable bit-field types other than _Bool, signed int, and unsigned int (6.7.2.1).
Whether a bit-field can straddle a storage-unit boundary (6.7.2.1).
The order of allocation of bit-fields within a unit (6.7.2.1).
The alignment of non-bit-field members of structures (6.7.2.1).
The integer type compatible with each enumerated type (6.7.2.2).
這一段其實在
Annex J
J.3 Implementation-defined behavior
J.3.9 Sturctures, unions, enumerations and bit-fields
中寫著
另外,groups裡找到一個不錯的帖子,大概說了

1. bit-field自己對齊之外,還要記得考慮structures, unions的對齊要求,所以還會有padding

2.
`int' is a poor choice for 1-bit bit-fields, since it can
designate either a signed or unsigned int and thus the only value
it is required to hold is 0.

See C99 6.7.2#5:

Each of the comma-separated sets designates the same type,
except that for bit-fields, it is implementation-defined
whether the specifier int designates the same type as signed
int or the same type as unsigned int.

另外一篇文章裡也講到了一些例子
http://www.yuanma.org/data/2006/0619/article_864.htm

struct foo4 {
char a:2;
char b:3;
int c:1;
};

sizeof(struct foo4)為4,儘管char, int自己的對齊要求不一樣(一個位元組,一個是4位元組 - 32位機器上),但是bit-field是一個獨立的概念,有自己的對齊建議(6.7.2.1 10)

相關推薦

C語言變數宣告冒號用法 稱為

 有些資訊在儲存時,並不需要佔用一個完整的位元組, 而只需佔幾個或一個二進位制位。例如在存放一個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省儲存空間,並使處理簡便,C語言又提供了一種資料結構,稱為“位域”或“位段”。所謂“位域”是把一個位元組中的二進位劃

C語言變數宣告冒號用法

有些資訊在儲存時,並不需要佔用一個完整的位元組, 而只需佔幾個或一個二進位制位。例如在存放一個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省儲存空間,並使處理簡便,C語言又提供了一種資料結構,稱為“位域”或“位段”。所謂“位域”是把一個位元組中的二進位劃分為

C語言 struct結構體的變數宣告冒號

有些資訊在儲存時,並不需要佔用一個完整的位元組,而只需佔幾個或一個二進位制位。例如在存放一個開關量時,只有0和1兩種狀態,用一位二進位即可。 為了節省儲存空間,並使處理簡便,C語言又提供了一種資料結

C++ 中變數宣告中 const 用法

一直以來對 C++ 中的 const 說明符理解不夠清晰,尤其是在變數宣告時處於何種位置起到何種作用,分辨不清。 現在花費一些時間專門理清其中的關係,明白其中的道理之後,就再也不會混淆了。文中內容主要參考了這篇譯文。 1. 幾個概念 以 static unsig

C語言變數宣告記憶體分配

原址:http://blog.csdn.net/liu_xueping/article/details/40079145 一個由c/C++編譯的程式佔用的記憶體分為以下幾個部分 1、棧區(stack)— 程式執行時由編譯器自動分配,存放函式的引數值,區域性變數的值等

C語言變數宣告問題——變數定義一定要放在所有執行語句/語句塊的最前面嗎?

參考網址:http://www.cnblogs.com/web-HCJ/p/4468689.html 報錯資訊:error C2065: 'salary' : undeclared identifier 1 2 3 4 5 6 7 8 9

c語言變數宣告與定義_extern

1  c語言中變數的宣告與定義 定義:在c語言中變數的定義為:”資料型別+變數名“的形式,比如 int a;系統會給定義的變數分配記憶體空間。變數的定義只能有一次。 宣告:對於變數的宣告來說,形式為:“宣告型別 + 資料型別 + 變數名”。比如 extern int a;

C語言中關鍵詞static的用法與作用

細心 錯誤 不同 color 運行程序 可能 gpo 需要 之間 一、面向過程設計中的static 轉載:http://blog.csdn.net/celerylxq/article/details/6160499 1、靜態全局變量 在全局變量前,加上關鍵字stati

C語言知識點學習之結構體成員變數冒號

typedef struct xx {        unsigned int a:2;      unsigned int b:3; }Xx; //“unsigned int a:2;“中後面的":2"表示成員a只佔倆個位,而不是我們傳統認為的佔 //4個位元組這樣整個結構體大小就為4個位元組而不是8

C語言結構體中冒號()用法

位域出現的原因是由於某些資訊的儲存表示只需要幾個bit位就可以表示而不需要一個完整的位元組,同時也是為了節省儲存空間和方便處理。   typedef struct  bit_struct {     int &n

C語言宣告與定義

keil的專案中,遇到呼叫其他C檔案函式和變數的情況: 對於函式,在a.c下面進行編寫,之後在a.h下面進行宣告,其他檔案包含a.h即可呼叫。 對於變數,在a.c下面進行定義,在a.h下面也要進行一下宣告,其他檔案使用此變數時,包含a.h即可使用。 關於變數的定義與宣告 變數定義即為

c語言getchar()的用法

c語言getchar的用法: 1.從緩衝區讀走一個字元,相當於清除緩衝區 2.前面的scanf()在讀取輸入時會在緩衝區中留下一個字元’\n’(輸入完s[i]的值後按回車鍵所致), 所以如果不在此加一個getchar()把這個回車符取走的話,gets()就不會等待從鍵盤鍵入字元,

C語言變數定義與微控制器資料儲存方式

說明:文章來源 EDN電子技術設計:嵌入式程式開發需要知道的儲存器知識 MCU 中常使用的儲存器型別有:FLASH、RAM、ROM(包括EEPROM) 在軟體角度來看,程式和資料的儲存分為以下幾個部分 程式碼段和常量段都可以用於儲存常量資料,其主要區

C語言---變數儲存期

    作用域和連結描述了識別符號的可見性。儲存期描述了通過這些識別符號訪問的物件的生存期。C物件有4種儲存期:靜態儲存期、執行緒儲存期、自動儲存期、動態分配儲存期。     如果物件具有靜態儲存期,那麼它在程式的執行期間一直存在。檔案作用域變數具有靜態儲存

break和continue,C語言break和continue的用法和區別

break 語句很重要,用得非常多,初學者一定要掌握。continue 語句雖然沒有 break 語句用得多,但也經常用到,而且不可或缺,需要用到 continue 的時候其他語句是無法替代的。 前面已經介紹過 break 語句,它不僅可以跳出“迴圈體”,還可以跳出 switch。但事實上,br

C語言變數

1.1 變數 我先舉一個例子,如果我有一個倉庫,我想把一些東西放進去,比如蘋果、西瓜等等。 1、首先,我是不是應該要知道我要放的東西體積多大,還有就是 需要找多大的空間能放得下它。 計算機的儲存空間就相當於這裡的倉庫。 2、對倉庫來說它並不知道是蘋果還是西瓜,它只知道存放的是體積不一

Leetcode演算法題(C語言)8--

題目:加一 給定一個由整陣列成的非空陣列所表示的非負整數,在該數的基礎上加一。 最高位數字存放在陣列的首位, 陣列中每個元素只儲存一個數字。 你可以假設除了整數 0 之外,這個整數不會以零開頭。 示

C語言宣告與定義

前言 引用性宣告 不分配儲存空間,如extern int x; 只是告訴編譯器x是整形,已經在其它地方定義了。 定義 是在記憶體中確定變數的位置、大小。 初始化 是定義變數時候賦給變數的值(從無到有)

C語言】實際專案開發過程中常用C語言函式的9大用法

C語言是當中最廣泛的計算機程式語言,是所有計算機程式語言的祖先,其他計算機程式語言包括當前流行的Java語言,都是用C語言實現的,C語言是程式設計效率最高的計算機語言,既能完成上層應用開發,也能完成底層硬體驅動程式設計,在計算機程式設計當中,特別是在底層硬體驅動開發當中,具有不可替代的作用。

C語言變數定義與資料溢位(初學者)

1、變數定義的一般形式為:型別說明符、變數名識別符號等;例:int a,b,c;(abc為整型變數) 在書寫變數定義時應注意以下幾點: (1)允許在一個型別說明符後,定義多個相同型別的變數。各變數之間用“,”間隔。型別說明符與變數名之間用一個空格間隔。 (2)最後一個變數之後必須以“;”結尾。 (3)