C 结构体指针初始化
在使用指针之前,务必要将其初始化。这个是我们最早学习 C 语言的时候,书上经常说的一个问题。在工作中,我们反而会经常忘记这条金科玉律。
本篇文章的所有代码都经 gcc-7
编译器编译过。关于在 macOS 中如何安装和使用 gcc
,可以参考 GCC: Homebrew 安装 GCC 和 Binutils 这篇文章。
结构体成员指针的初始化
结构体成员指针的初始化,指的是初始化结构体中指针变量的成员。
我们举个例子,下面是 Animal
的结构体。
1 2 3 4 5 6 struct Animal { char *name; int age; char info[200 ]; struct Animal *nextAnimal ; };
结构体 Animal
含有4个成员变量,其中 name
、info
和 nextAnimal
是指针变量。
写一段测试代码,如下:
1 2 3 4 5 6 7 8 int main (int argc, const char *argv[]) { struct Animal animal ; printf ("animal's name: %s, age: %i, info: %s\n" , animal.name, animal.age, animal.info); return 0 ; }
运行结果正常,终端输出如下:
1 animal's name: (null), age: 0, info:
我们来验证一下 Animal *nextAnimal
在没有初始化的情况下,会不会有什么问题。
1 2 3 4 5 6 7 8 9 10 11 12 int main (int argc, const char *argv[]) { struct Animal animal ; 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 ; }
程序编译没有问题,运行报错
1 2 3 animal' s name: (null), age: 0 , info: animal.nextAnimal: 0x1127fa036 Segmentation fault: 11
修改一下代码,初始化一下 animal.nextAnimal
这个指针,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int main (int argc, const char *argv[]) { struct Animal animal ; 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
这个变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 int main (int argc, const char *argv[]) { struct Animal animal ; 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" ; printf ("animal.nextAnimal->name: %s, age: %i, info: %s\n" , animal.nextAnimal->name, animal.nextAnimal->age, animal.nextAnimal->info); return 0 ; }
编译运行,一切正常。
1 2 3 animal' s name: (null), age: 0 , info: animal.nextAnimal: 0x10f0f1036 animal.nextAnimal->name: cat, age: 0 , info:
通过上面的例子,结构体指针变量有些会给默认值,有些又不会给,所以都要初始化指针变量。修改一下代码,示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #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 Animal animal ; 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 ; }
结构体指针的初始化
指的是初始化结构体指针变量。
1 2 3 4 5 6 7 8 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 ; }
编译运行报错:
同样的道理,需要初始化指针变量。完成后的示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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); 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 #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 Animal animal ; 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); 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 ; }
编译
运行
运行结果如下:
1 2 3 4 5 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
小荷才露尖尖角,早有蜻蜓立上头~