Linux--结构体的详细学习
1.結構體的聲明
聲明的一般形式:
struct 結構體名
{
結構體所包含的成員的成員變量
};
struct stu
{
char name[20];
int num;
int age;
char group;
float score;
};
stu 為結構體名,它包含了5個成員,分別是name、num、age、group、score。
2.定義結構體變量
struct stu s1,s2;
struct stu
{
char name[20];
int num;
int age;
char group;
float score;
}s1,s2;
上面s1,s2是結構體變量。
3.結構體變量賦值與使用
struct stu stu1 ={“Tom”,12,8,‘A’,136.5};
struct stu stu1 ={.name=“TOm”,.num=12,.age=18,.group=‘A’,.score=136.5};
struct stu
{
char *name;
int num;
int age;
char group;
float score;
}s1={“Tom”,12,18,‘A’,136.5};
訪問結構體成員變量是使用點號操作符.
stu1.name=“Tom’;
stu1.num=12;
stu1.age=18;
stu1.group=‘A’;
stu1.score=136.5;
4.結構體數組
struct student stu[5]={{“xiaoming”,20,15},{“xiaohong”,21,80},{“wanglei”,18,59},{“wangping”,19,90},{“leifeng”,19,99}};
5.結構體嵌套
struct A
{
char ch;
char a;
char ch1;
};
struct B
{
int i;
struct A a;
};
6.結構體指針
6.1結構體和結構體變量是不同的概念。
6.2結構體是一種數據類型,和我們平時的 int,float等是一樣的,編譯器不會為他們分配內存。
6.3結構體變量才是實實在在的數據,才需要內存來存儲。
struct student stu ={“xiaoming”,18,50};//結構體變量
struct student psu=&stu;//結構體指針,指向一個結構體變量stu
//struct student pstu =student;//錯誤的寫法;
獲取結構體成員:
// .號優先級高于,(*psu)兩邊的括號是不能少的,如果去掉括號
//就變成了 psu.name=(psu.name)
printf(“name=%s\n”,(*psu).name);
//->是一個新的運算符,一般叫做"箭頭”,通過她接過體指針能直接取得到結構體的成員
printf(“name=%s\n”,psu->name);
結構體變量名代表的是整個集合本身,作為函數參數時傳遞的是整個集合,也就是所有的成員,而不是像數組那樣被編譯轉換成一個指針。如果結構體成員較多,尤其是成員維數組時,傳送的時間和空間開銷會很大,影響程序運行效率,所以最好的辦法就是使用結構指針,這時有實參傳向形參的只是一個地址,非常快速。
7.結構體的位域
7.1位域的定義:
有些數據在存儲時并不需要占用一個完整的字節,只需要占用一個或幾個二進制位即可。例如開關只有通電和斷電兩種狀態,用 0 和 1 表示足以,也就是用一個二進位。正是基于這種考慮,C語言又提供了一種叫做位域的數據結構。
在結構體定義時,我們可以指定某個成員變量所占用的二進制位數(Bit),這就是位域:
struct bs
{
unsigned m;
unsigned n:4;
unsigned char ch 6;
};
7.2位域的具體存儲規則
7.2.1相鄰成員的類型相同時
當相鄰成員的類型相同時,如果它們的位寬之和小于類型的 sizeof 大小,那么后面的成員緊鄰前一個成員存儲,直到不能容納為止;如果它們的位寬之和大于類型的 sizeof 大小,那么后面的成員將從新的存儲單元開始,其偏移量為類型大小的整數倍。
struct bs
{
unsigned m:6;
unsigned n:12;
unsigned p:8;
};
printf("%d\n",sizeof(struct bs));
答案為4.
7.2.2相鄰成員類型不同時
當相鄰成員的類型不同時,不同的編譯器有不同的實現方案,GCC 會壓縮存儲,而 VC/VS 不會
struct bs
{
unsigned m:6;
unsigned char ch:12;
unsigned p:8;
};
printf("%d\n",sizeof(struct bs));
答案為4.
struct bs
{
unsigned m:6;
unsigned char ch:12;
unsigned p:16;
};
printf("%d\n",sizeof(struct bs));
答案為8.
這兩個就明顯的體現了gcc編譯器壓縮的特性。
7.2.3響鈴成員之間穿插著非位域成員時
如果成員之間穿插著非位域成員,會視情況進行壓縮。例如對于下面的 bs:
struct bs
{
unsigned m:6;
unsigned char ch;
unsigned p:13;
};
printf("%d\n",sizeof(struct bs));
答案為8.
struct bs
{
unsigned m:4;
unsigned char ch;
unsigned p:13;
};
printf("%d\n",sizeof(struct bs));
答案為4.
這兩個程序運行后的結果體現了gcc編譯器壓縮的特性.
7.2.4位域成員可以沒有名稱,只給出數據類型和位寬
位域成員可以沒有名稱,只給出數據類型和位寬
struct bs
{
int n :12;
unsigned :20 ;
unsigned p:4;
};
printf("%d\n",sizeof(struct bs));
無名位域一般用來作填充或者調整成員位置。因為沒有名稱,無名位域不能使用。
上面的例子中,如果沒有位寬為 20 的無名成員,m、n 將會挨著存儲,sizeof(struct bs) 的結果為 4;有了這 20 位作為填充,m、n 將分開存儲,sizeof(struct bs) 的結果為 8。
總結
以上是生活随笔為你收集整理的Linux--结构体的详细学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下main函数带参数问题和at
- 下一篇: Linux下静态库的创立与使用