結構體在宣告的時候並沒有分配任何的記憶體資源,只有定義了結構體變數才會產生相應的記憶體分配。
#define
僅僅是做簡單的替換,而typedef是給某種資料型別建立乙個替代名。
看這樣的例子:
#include
#define charp char*
int main()
編譯:
$ gcc typedef.c
typedef.c: in function 『main』:
typedef.c:4:29: warning: initialization makes integer from pointer without a cast
charp s1="i love you.", s2="hello";
^
typedef:
#include
typedef
char* charp;
int main()
編譯:
$ gcc typedef.c
#include
typedef
struct nodenode;
int main()
#include
#include
typedef
struct nodenode;
int main()
/*edemon@ubuntu1:~/workspace$ ./a.out
s is hello, a is 12, b is 2.500000
*/
結構體定義中含有另一種結構體,這是合法的:
struct point;
struct trangle;
但是含有自身型別就是非法的了。
struct trangle;
/*$ gcc struct1.c
struct1.c:8:17: error: array type has incomplete element type
struct trangle p[3];
^*/
結構體定義中可以擁有指向自身型別結構的指標。這樣的自指結構是合法的。
struct trangle;
自指結構最典型的應用就是鍊錶。
和c++不同,c不能在結構體中定義函式,因為c約定結構和演算法(函式)是分開的。
看下面的**:
struct man
};int main(void)
直接編譯,我們會得到這樣的資訊:error: 『struct man』 has no member named 『show』
而如果是在c++ 中編譯,這不會有問題。
c++ 中的struct是有this指標的,如下**可以正常執行:
struct man
void show()
};
結構體中的成員預設都是public的。
結構體不能包含顯式的無參建構函式。如:
struct man
man()
void show()
};int main(void)
我們將得到:
error: request for
member 『show』 in 『man2』, which is of non-class
type 『man()』
將man()刪除仍然有這樣的錯誤,這是為什麼,因為結構體是沒有預設的建構函式的,涉及到initobj等指令。
結構從基類object繼承,但它不支援繼承。
聯合變數的儲存區域可以儲存多型別的資料。但是在任何時候,它只能儲存一種資料,聯合變數的大小是size最大成員的大小。
下面是乙個聯合的例子,涉及到c++的typeid操作符,用於判斷資料型別。
#include
#include
#include
using
namespace
std;
union numbers;
int main()
執行:
# ./a.out
typeid
return c, out data type size is
1, union numbers size is
8typeid
return i, out data type size is
4, union numbers size is
8typeid
return f, out data type size is
4, union numbers size is
8typeid
return d, out data type size is
8, union numbers size is
8
在聯合的定義中可以存在另一種不同的聯合型別。比如:
union numbers;
union union;
和結構體是一樣的,它不能自身巢狀定義,比如:
union union
;
我們也能定義含有指向自身型別的指標的聯合型別。
union union
;
在這種情況下,num的型別已經改變,不再是自身。
首先複習一下位元組、位等關鍵概念。byte為位元組,bit即位。轉換
1b = 8b; 1kb = 1024b; 1mb = 1024kb; 1gb = 1024mb.
使用位欄位,結構的成員被壓縮到了一起,允許程式設計師在位的層次上訪問記憶體,節省儲存空間。注:位字段的資料型別必須是(signed) int、unsigned int。同時,位欄位型別變數
不能位址操作 //--> error: cannot take address of bit-field 『field1』
不能計算位元組數,sizeof
看看這個例子:
#include
#include
struct temp;
int main()
編譯執行
[root@centos workspace]# gcc bit.c
[root@centos workspace]# ./a.out
struct temp size is
12
field1和field2的記憶體占用是3個位元組,int資料型別的位元組數是4,所以最終結構體的記憶體占用是4+8 = 12.
通過列舉,我們可以定義自己的幾種可能值的資料型別。
在預設的情況下,第乙個值和0關聯,第二個值和1關聯…
c語言中沒有布林資料型別,我們可以自定義。
比如:
#include
#include
enum boolean ;
typedef
enum boolean bool;
bool check(int tag)
int main()
如果是自定義列舉成員的值,那麼未自定義的成員按照順序增大的原則賦值。比如:
#include
#include
enum node;
int main()
/*[root@centos workspace]# ./a.out
t2 is 2, t4 is 6, t5 is 7
*/
值得注意的是,enum的變數可以被任意賦值(不過只能給列舉變數賦值整數哈),不一定是定義的列舉成員。
#include
#include
enum node;
int main()
結構 聯合 位欄位
1 結構體空洞 結構欄位在儲存器中並不一定是挨著擺放的,有時兩個字段之間會有小的空隙。因為計算機總希望資料能對齊字邊界,如果計算機的字長是32位,就不希望某個變數跨越32位的邊界儲存。因為計算機按字從儲存器中讀取資料,如果某個字段跨越了多個字,cpu就必須讀取多個儲存單元,並以某種方式把督導的值合併...
位段,列舉,聯合
前面我們說過了自定義型別,包含結構體,位段,列舉,聯合。前一篇我們總結了結構體,今天來說一下位段,列舉,聯合。一 位段 1 位段概念 c語言中允許在乙個結構體中以位為單位來指定其成員所佔記憶體長度,這種以位為單元的成員稱為 位段 或 位域 1 位段的成員可以是int,unsigned int,sig...
位段 列舉 聯合
2.列舉 3.聯合 1.位段的成員必須是 int,unsigned int signed 即必須是整形家族 這是因為位段的成員是以位元位為單位進行儲存的,假如是浮點型別,給成員乙個5.3的容量,0.3的位元位去 找呢?2.位段的成員名後面有乙個冒號和數字 3.具體宣告如下 1.平時我們開闢空間都是偶...