C 結構體指標初始化
在使用指標之前,務必要將其初始化。這個是我們最早學習 C 語言的時候,書上經常說的一個問題。在工作中,我們反而會經常忘記這條金科玉律。
本篇文章的所有程式碼都經 gcc-7
編譯器編譯過。關於在 macOS 中如何安裝和使用 gcc
,可以參考 GCC: Homebrew 安裝 GCC 和 Binutils 這篇文章。
結構體成員指標的初始化
結構體成員指標的初始化,指的是初始化結構體中指標變數的成員。
我們舉個例子,下面是 Animal
的結構體。
struct Animal{ char *name; //指標成員 int age; char info[200]; //字元陣列,本質也是指標變數 struct Animal*nextAnimal; //指標成員 };
結構體 Animal
含有4個成員變數,其中 name
、 info
和 nextAnimal
是指標變數。
寫一段測試程式碼,如下:
int main(int argc, const char *argv[]) { struct Animalanimal; printf("animal's name: %s, age: %i, info: %s\n", animal.name, animal.age, animal.info); return 0; }
執行結果正常,終端輸出如下:
animal's name: (null), age: 0, info:
我們來驗證一下 Animal *nextAnimal
在沒有初始化的情況下,會不會有什麼問題。
int main(int argc, const char *argv[]) { struct Animalanimal; printf("animal's name: %s, age: %i, info: %s\n", animal.name, animal.age, animal.info); printf("animal.nextAnimal: %p\n", animal.nextAnimal); printf("animal.nextAnimal->name: %s, age: %i, info: %s\n", animal.nextAnimal->name, animal.nextAnimal->age, animal.nextAnimal->info); return 0; }
程式編譯沒有問題,執行報錯
animal's name: (null), age: 0, info: animal.nextAnimal: 0x1127fa036 Segmentation fault: 11
修改一下程式碼,初始化一下 animal.nextAnimal
這個指標,如下:
int main(int argc, const char *argv[]) { struct Animalanimal; printf("animal's name: %s, age: %i, info: %s\n", animal.name, animal.age, animal.info); printf("animal.nextAnimal: %p\n", animal.nextAnimal); // 初始化指標變數 animal.nextAnimal = (struct Animal *)malloc(sizeof(struct Animal)); printf("animal.nextAnimal->name: %s, age: %i, info: %s\n", animal.nextAnimal->name, animal.nextAnimal->age, animal.nextAnimal->info); return 0; }
再次編譯重新執行,還是報錯。還需要初始化 animal.nextAnimal->name
這個變數。
int main(int argc, const char *argv[]) { struct Animalanimal; printf("animal's name: %s, age: %i, info: %s\n", animal.name, animal.age, animal.info); printf("animal.nextAnimal: %p\n", animal.nextAnimal); // 初始化指標變數 animal.nextAnimal = (struct Animal *)malloc(sizeof(struct Animal)); // 初始化 name 變數 animal.nextAnimal->name = "cat"; printf("animal.nextAnimal->name: %s, age: %i, info: %s\n", animal.nextAnimal->name, animal.nextAnimal->age, animal.nextAnimal->info); return 0; } ``` 編譯執行,一切正常。 ```c animal's name: (null), age: 0, info: animal.nextAnimal: 0x10f0f1036 animal.nextAnimal->name: cat, age: 0, info:
通過上面的例子,結構體指標變數有些會給預設值,有些又不會給,所以都要初始化指標變數。修改一下程式碼,示例如下:
#include<stdio.h> #include<stdlib.h> #include<string.h> struct Animal{ char *name; //指標成員 int age; char info[200]; //字元陣列,本質也是指標變數 struct Animal*nextAnimal; //指標成員 }; int main(int argc, const char *argv[]) { struct Animalanimal; animal.name = "cat"; strcpy(animal.info, "This is a cat."); printf("animal's name: %s, age: %i, info: %s\n", animal.name, animal.age, animal.info); printf("animal.nextAnimal: %p\n", animal.nextAnimal); // 初始化指標變數 animal.nextAnimal = (struct Animal *)malloc(sizeof(struct Animal)); // 初始化變數 animal.nextAnimal->name = "cat"; strcpy(animal.nextAnimal->info, "This is a cat."); printf("animal.nextAnimal->name: %s, age: %i, info: %s\n", animal.nextAnimal->name, animal.nextAnimal->age, animal.nextAnimal->info); return 0; }
結構體指標的初始化
指的是初始化結構體指標變數。
int main(int argc, const char *argv[]) { struct Animal*ptAnimal; printf("ptAnimal's name: %s, age: %i, info: %s\n", ptAnimal->name, ptAnimal->age, ptAnimal->info); return 0; }
編譯執行報錯:
Segmentation fault: 11
同樣的道理,需要初始化指標變數。完成後的示例程式碼如下:
int main(int argc, const char *argv[]) { struct Animal*ptAnimal; // 初始化結構體指標 ptAnimal = (struct Animal *)malloc(sizeof(struct Animal)); ptAnimal->name = "dog"; strcpy(ptAnimal->info, "This is a big dog"); printf("ptAnimal's name: %s, age: %i, info: %s\n", ptAnimal->name, ptAnimal->age, ptAnimal->info); // 初始化結構體指標的成員指標變數 nextAnimal ptAnimal->nextAnimal = (struct Animal *)malloc(sizeof(struct Animal)); ptAnimal->nextAnimal->name = "dog"; strcpy(ptAnimal->nextAnimal->info, "This is a big dog"); printf("ptAnimal->nextAnimal's name: %s, age: %i, info: %s\n", ptAnimal->nextAnimal->name, ptAnimal->nextAnimal->age, ptAnimal->nextAnimal->info); return 0; }
完整示例
main.c
#include<stdio.h> #include<stdlib.h> #include<string.h> struct Animal{ char *name; //指標成員 int age; char info[200]; //字元陣列,本質也是指標變數 struct Animal*nextAnimal; //指標成員 }; int main(int argc, const char *argv[]) { /// 驗證結構體指標成員變數 { struct Animalanimal; animal.name = "cat"; strcpy(animal.info, "This is a cat."); printf("animal's name: %s, age: %i, info: %s\n", animal.name, animal.age, animal.info); printf("animal.nextAnimal: %p\n", animal.nextAnimal); // 初始化指標變數 animal.nextAnimal = (struct Animal *)malloc(sizeof(struct Animal)); // 初始化變數 animal.nextAnimal->name = "cat"; strcpy(animal.nextAnimal->info, "This is a cat."); printf("animal.nextAnimal->name: %s, age: %i, info: %s\n", animal.nextAnimal->name, animal.nextAnimal->age, animal.nextAnimal->info); } /// 驗證結構體指標 { struct Animal*ptAnimal; // 初始化結構體指標 ptAnimal = (struct Animal *)malloc(sizeof(struct Animal)); ptAnimal->name = "dog"; strcpy(ptAnimal->info, "This is a big dog"); printf("ptAnimal's name: %s, age: %i, info: %s\n", ptAnimal->name, ptAnimal->age, ptAnimal->info); // 初始化結構體指標的成員指標變數 nextAnimal ptAnimal->nextAnimal = (struct Animal *)malloc(sizeof(struct Animal)); ptAnimal->nextAnimal->name = "dog"; strcpy(ptAnimal->nextAnimal->info, "This is a big dog"); printf("ptAnimal->nextAnimal's name: %s, age: %i, info: %s\n", ptAnimal->nextAnimal->name, ptAnimal->nextAnimal->age, ptAnimal->nextAnimal->info); } return 0; }
編譯
gcc-7 main.c -o main
執行
./main
執行結果如下:
animal's name: cat, age: 0, info: This is a cat. animal.nextAnimal: 0x0 animal.nextAnimal->name: cat, age: 0, info: This is a cat. ptAnimal's name: dog, age: 0, info: This is a big dog ptAnimal->nextAnimal's name: dog, age: 0, info: This is a big dog
掃碼關注,你我就各多一個朋友~