C語言:constkeyword、結構體
前幾節內容的解說,主要是內存地址及指針的分析。這一節解說一下easy混淆的keywordconstant及結構體的知識。
一、constkeyword
1. 字符常量的指針
char const *p1 = "hello"; printf("指針的值:%p,指針所指向的值:%c\n",p1, *p1); p1++; printf("指針的值:%p,\n",p1);上例中。p1就是字符常量的指針,它的特點: 指針的值能夠被改動。指針所指向的值不能被改動。
因此。p1++ 這個操作是能夠的,打印結果例如以下:
指針的值:0x100000f22,指針所指向的值:h
指針的值:0x100000f23
我們再來試著書寫 (*p1)++; 這個操作。首先通過 *p1 操作獲得字符串 "hello" 中的 h, 然後進行 "++" 操作,然而此時,"hello" 是僅僅讀的,所以這句代碼在編譯期間就會報錯了。
2. 字符的常量指針
char *const p2 = "world"; printf("指針的值:%p,指針所指向的值:%c",p2, *p2);上例中,p1就是字符的常量指針。它的特點: 指針的值不能夠被改動,指針指向的值能夠被改動。
打印結果:
指針的值:0x100000f64,指針所指向的值:w
我們再來試著書寫 p2++; 這個操作。此時在編譯期間就會報錯,由於 p2 是僅僅讀的。
*p2 = ‘k‘;這個操作在編譯期間不會報錯,所以不違反"指針指向的值能夠被改動"這一規則,可是它會在執行期間報錯,由於字符串"world" 是存儲在僅僅讀存儲區的。
二、 結構體
在C中,使用結構體能夠把不同類型的值存儲在一起,因此結構體是一些值的集合,這些值稱為它的成員。
在數組中能夠通過下標訪問。僅僅是由於數組的元素長度同樣。
而結構體是不能夠的,所以在結構體中,每一個成員都有自己的名字,他們是通過名字訪問的。
結構體的申明
方式一:基本聲明
struct { int a; char b; float c; } x; struct { int a; char b; float c; } y[20], *z;
第一個結構聲明創建了一個名字叫x得變量。它包括三個成員:一個整數,一個字符和一個浮點數。
第二個結構聲明創建了y和z,y是一個數組,它包括了20個結構。z是一個指針,它指向這個類型的結構。
可是。這兩個聲明被編譯器當做兩種截然不同的類型。即使它們的成員列表全然同樣,由於 z = &x; 是錯誤的寫法。
方式二:標簽聲明
struct SIMPLE { int a; char b; float c; };標簽同意多個聲明使用同一個成員列表。
這個聲明把標簽SIMPLE和這個成員列表聯系在一起。該聲明並沒有提供變量列表,所以它並為創建不論什麽變量。
struct SIMPLE x; struct SIMPLE y[20], *z; z = &x;而且此時 z = &x; 是全然能夠的。由於x與z所指向的結構是同一種類型的結構。
方式三: typedef聲明
typedef struct { int a; char b; float c; } SIMPLE;這個技巧和聲明一個結構標簽效果差點兒同樣。差別在於Simple如今是個類型名而不是個結構標簽。
所以興許的聲明可能像以下這個樣子:
SIMPLE x; SIMPLE y[20], *z;
結構體的使用
定義例如以下結構體
typedef struct { int a; short b[2]; } Ex2; typedef struct Ex { int a; char b[3]; Ex2 c; struct Ex *d; } Ex;
結構Ex2中有一個整形成員和一個short數組;結構Ex中有一個整形成員。一個字符數組,一個Ex2結構,一個指向Ex結構的指針變量。
以下,對他們進行初始化工作
Ex x = {10, "Hi", {5, {-1 ,25} }, 0}; Ex *px = &x;分析一下結果:
printf("px 存放的內容:%p\n",px);px中存放的內容就是結構體x的地址。
Ex accept = *px;*px就是獲取px所指向的整個結構體的值。
printf("結構x的變量a的值:%d,%d\n",x.a, px->a);訪問結構體成員的兩種方式:
1. 結構體.變量名
2. 指針名->變量名
printf("結構x的變量a的地址:%p", &px->a);
獲取結構中成員變量的地址(註意:這裏打印的地址盡管和px的地址一樣。可是含義不同:px表示整個結構的地址,而&px->a表示結構x中變量a所在的地址。因為變量a是結構的首元素。所以和整個結構的地址是一致的)。
C語言:constkeyword、結構體