C结构体指针初始化
在使用指针之前,务必要将其初始化。这个是我们最早学习 C 语言的时候,书上经常说的一个问题。在工作中,我们反而会经常忘记这条金科玉律。
结构体成员指针的初始化
结构体成员指针的初始化,指的是初始化结构体中指针变量的成员。
我们举个例子,下面是 Animal
的结构体,定义在animal.h
头文件中:
struct Animal {
char *name; //指针成员
int age;
char info[200]; //字符数组
struct Animal *nextAnimal; //指针成员
};
结构体 Animal
含有4个成员变量,其中 name
、info
和 nextAnimal
是指针变量。
测试函数都是在main函数中执行,省略了main
函数;
写一段测试代码,如下:
void test01(){
struct Animal animal;
printf("name:%s, age:%i, info:%s\n", animal.name, animal.age, animal.info);
}
运行结果正常,终端输出如下:
name:(null), age:0, info:
来验证一下 Animal *nextAnimal
在没有初始化的情况下,会不会有什么问题:
void test02(){
struct Animal animal;
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);
}
程序编译没有问题,运行报错:
animal.nextAnimal:0x400a4d
Signal: SIGSEGV (Segmentation fault)
修改一下代码,初始化一下 animal.nextAnimal
这个指针,如下:
void test03(){
struct Animal animal;
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);
}
再次编译,重新运行正常:
animal.nextAnimal:0x400a4d
animal.nextAnimal->name:cat,age:0,info:
还需要初始化 animal.nextAnimal->name
这个变量:
void test04(){
struct Animal animal;
animal.name = "cat";
strcpy(animal.info, "This is a cat!");
printf("name:%s, age:%i, info:%s\n", animal.name, animal.age, animal.info);
//name:cat, age:1467878128, info:This is a cat!
printf("animal.nextAnimal:%p\n", animal.nextAnimal);
//初始化结构体指针
animal.nextAnimal = (struct Animal *)malloc(sizeof(struct Animal));
animal.nextAnimal->name = "dog";
strcpy(animal.nextAnimal->info, "This is a dog!");
printf("animal.nextAnimal->name:%s,age:%i,info:%s\n",animal.nextAnimal->name,
animal.nextAnimal->age, animal.nextAnimal->info);
//animal.nextAnimal->name:dog,age:0,info:This is a dog!
}
编译运行,一切正常:
name:cat, age:0, info:This is a cat!
animal.nextAnimal:0x400a4d
animal.nextAnimal->name:dog,age:0,info:This is a dog!
通过上面的例子,结构体指针变量有些会给默认值,有些又不会给,所以都要初始化指针变量。
结构体指针的初始化
指的是初始化结构体指针变量。
void test05(){
struct Animal *pAnimal;
printf("name:%s, age:%i, info:%s\n", pAnimal->name, pAnimal->age, pAnimal->info);
}
编译运行报错:
Signal: SIGSEGV (Segmentation fault)
同样的道理,需要初始化指针变量。完成后的示例代码如下:
void test06(){
struct Animal *pAnimal;
//初始化结构体指针
pAnimal = (struct Animal*)malloc(sizeof(struct Animal));
pAnimal->name = "dog";
strcpy(pAnimal->info, "This is a dog!!!");
printf("name:%s, age:%i, info:%s\n", pAnimal->name, pAnimal->age, pAnimal->info);
pAnimal->nextAnimal = (struct Animal*)malloc(sizeof(struct Animal));
pAnimal->nextAnimal->name = "puppy";
strcpy(pAnimal->nextAnimal->info, "This is a puppy.");
printf("pAnimal->nextAnimal->name:%s,age:%i,info:%s\n",pAnimal->nextAnimal->name,
pAnimal->nextAnimal->age, pAnimal->nextAnimal->info);
}
完整示例
animal.h
头文件
#ifndef LINUX_C_ANIMAL_H
#define LINUX_C_ANIMAL_H
#endif //LINUX_C_ANIMAL_H
struct Animal{
char *name;
int age;
char info[200];
struct Animal *nextAnimal;
};
animal.c
文件
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include "animal.h"
void test01(){
struct Animal animal;
printf("name:%s, age:%i, info:%s\n", animal.name, animal.age, animal.info);
}
/**
* 指针未初始化使用,程序编译没有问题,运行会报错
*/
void test02(){
struct Animal animal;
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);
}
/**
* 动态分配内存空间后运行正确
*/
void test03(){
struct Animal animal;
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);
}
/**
* 结构体指针变量有些会给默认值,有些又不会给,所以都要初始化指针变量
* animal.age如果不赋值,则默认值可能是1467878128,不一定是0
*/
void test04(){
struct Animal animal;
animal.name = "cat";
strcpy(animal.info, "This is a cat!");
printf("name:%s, age:%i, info:%s\n", animal.name, animal.age, animal.info);
//name:cat, age:1467878128, info:This is a cat!
printf("animal.nextAnimal:%p\n", animal.nextAnimal);
//初始化结构体指针
animal.nextAnimal = (struct Animal *)malloc(sizeof(struct Animal));
animal.nextAnimal->name = "dog";
strcpy(animal.nextAnimal->info, "This is a dog!");
printf("animal.nextAnimal->name:%s,age:%i,info:%s\n",animal.nextAnimal->name,
animal.nextAnimal->age, animal.nextAnimal->info);
//animal.nextAnimal->name:dog,age:0,info:This is a dog!
}
/**
* 编译报错
*/
void test05(){
struct Animal *pAnimal;
printf("name:%s, age:%i, info:%s\n", pAnimal->name, pAnimal->age, pAnimal->info);
}
/**
* 使用结构体前都必须先初始化
*/
void test06(){
struct Animal *pAnimal;
//初始化结构体指针
pAnimal = (struct Animal*)malloc(sizeof(struct Animal));
pAnimal->name = "dog";
strcpy(pAnimal->info, "This is a dog!!!");
printf("name:%s, age:%i, info:%s\n", pAnimal->name, pAnimal->age, pAnimal->info);
pAnimal->nextAnimal = (struct Animal*)malloc(sizeof(struct Animal));
pAnimal->nextAnimal->name = "puppy";
strcpy(pAnimal->nextAnimal->info, "This is a puppy.");
printf("pAnimal->nextAnimal->name:%s,age:%i,info:%s\n",pAnimal->nextAnimal->name,
pAnimal->nextAnimal->age, pAnimal->nextAnimal->info);
}
int main(int argc, char *argv[]){
// test01();
// test02();
// test03();
// test04();
// test05();
test06();
return 0;
}