首先:一定要谨记C语言中未初始化变量不能拿来使用,不能作为函数参数,是可以以传地址方式作为函数参数.
前言:
一般来讲,我们会把初始化结构体的代码提取出来,封装到init()函数中,而通过将结构体变量作为函数参数来完成初始化,但有的时候比如,结构体变量作为参数,在初始化函数中用malloc动态分配内存,这样的行为不能完成外面的变量初始化.这就有可能导致未初始化函数使用的问题.
通过各种实验发现,首先要将函数中初始化过程分为两类:1.对结构体成员变量直接赋值2.使用malloc动态分配内存后赋值
typedef struct node
{
int h[99];
int m;
}k;
void init(int a,k * p) {
a = 9;
p->m = a;
}
int main() {
int a = 8;
k o ;
init(a,&o);
//c语言中,未初始化的变量,不可作为参数使用
}
这里,可以看到,o为结构体变量,但传的是地址,通过对地址直接赋值的方法是可以行的通的,而a则是传值,这,到初始化函数内,其a得到的也只是一个值.无论怎么修改,都影响不了外面的a值.
那么如果o为结构体指针变量呢?
typedef struct node
{
int h[99];
int m;
}k;
void init(int a,k * p) {
a = 9;
p->m = a;
}
int main() {
int a = 8;
k* o ;
init(a,o);
//c语言中,未初始化的变量,不可作为参数使用
}
修改过后,运行结果是o为未初始化变量,不可被使用.那么也就是说:作为指针变量需要先完成初始化(malloc() or 结构体变量赋值)被使用,而作为普通变量,并不需要先malloc(),然后再赋值.
有关malloc()函数什么时候用,有什么利弊,还是需要了解清楚了.
#include //动态分配函数和随机函数
typedef struct node
{
int h[99];
int m;
}k;
void init(int a,k * p) {
p=(k*)malloc(sizeof(k));
a = 9;
p->m = a;
}
int main() {
int a = 8;
k o ;
init(a,&o);
//c语言中,未初始化的变量,不可作为参数使用
}
可以发现,其init()函数后,o并没有发生变化,这是因为在init()函数内,原本p指针存的是变量o的地址,而通过动态分配内存后,p指针又指向了新的(变量)内存地址,这时就与o失去了联系.
#include //动态分配函数和随机函数
typedef struct node
{
int h[99];
int m;
}k;
void init(int a,k ** p) {
*p=(k*)malloc(sizeof(k));
a = 9;
(*p)->m = a;
}
int main() {
int a = 8;
k* o ;
init(a,&o);
//c语言中,未初始化的变量,不可作为参数使用
}
因为未初始化的指针不可直接作为参数使用,所以我们用到了二级指针来接收,指针变量的地址以此完成初始化过程.
从根本上看,指针是一个值为内存地址的变量(或数据对象),所以二级指针还是好理解的.
从结果上看,初始化过程是成功的.
我们用二级指针p去接收变量指针o的地址,然后用*p获取其值也就是变量指针o,这个时候我们也就直接是对变量指针o动态分配内存.也就完成了初始化.
1.c语言中,不管是普通变量,还是指针变量,未初始化时都不能直接拿来使用,但可以通过传地址的方式使用.
在使用malloc()初始化时,只能使用二级指针传递
在不使用malloc()时,其又分为值传递和引用即地址传递.
2.对未初始化变量函数中初始化有两种方式:
1.对结构体变量,采取直接赋值方式
2.对结构体指针变量,采取二级指针形参,然后动态分配空间后,赋值
3.malloc()函数的使用情况:
其为动态分配内存空间,在分配时需要强转指定类型,然后返回内存首地址,其一般用相关数据类型指针接收.
参考文档:
参考结构体