C语言结构体为何无法赋值?
struct Sap *SAP// 定义结构体指针
void TcpTest(void)
{
function1(SAP);
}
结构体的定义在文件名为“vars.h”的文件中:
struct Sap {
double X;
double Y;
double Z;
};
function1的具体定义在另一个文件function.c中:
在函数function1中先赋值(如下):
void function1(struct Sap *p)
{
p->X = 223885.23455;//赋值
p->Y = 457388.23755;//赋值
p->Z = 222388.44555;//赋值
printf("p_X = %lf", p->X);//查看
printf("p_Y = %lf", p->Y);//查看
printf("p_Z = %lf", p->Z);//查看
}
但后来发现赋值放不进去,以上三个printf输出的值全为0.0000;
后来单独建立了一个工程测试结构体的赋值操作,将所有定义和函数都写在main函数里,
还是用printf输出查看结构体的赋值情况,又是正常可以赋值的。
问题:
(1)在原任务函数中为何无法赋值?(printf语句查看全为0)
(2)为何在另外建的工程中可以正常赋值?
谢谢!
} 展开
问题一:
原任务中SAP是全局指针变量,虽然你没有进行初始化,但是根据编译器对全局变量的原则,所有全局或者静态变量会默认初始化为0(NULL)。如果一个指针被初始化为NULL,那自然是不能对其指向的成员进行赋值,赋值失败。
问题二:
接问题一,sap指针变量放在main里就是局部变量,编译器不会对其进行初始化,只分配变量内存,这里说的是指针变量的内存,保留其内存的内容。此时sap里的内容是随机的,也就是说它指向一个随机的内存地址。如果这个随机的地址,不受操作系统保护,那你依然可以进行赋值操作。这就是为啥放在main又可以赋值的原因,但是这个行为是非常危险的,因为用了本不应该属于你的内存,可能改变了其它数据的值,导致你的或者其它的程序不正常。
解决方案:
首先无论是全局还是局部指针变量,养成良好的习惯定义变量是同时初始化为NULL,在你要把它传递给函数时根据函数的需要对其进行真正的初始化,比如题目中是要申请内存。
同时在函数实现的代码中,如果函数要对指针成员进行赋值,那在之前可以对指针进行判断加入,如果是NULL那是不是直接退出提示错误。
if(p == NULL)
{
//没有初始化怎么操作的代码
}
这里会有个坑,如果在if里加入申请内存的代码是没有用的,因为只是改变了形参,实参改变不了,除非用二级指针,调用是传入指针的地址。
请问我另外单独建立了一个工程,把其他的语句全都去掉,只是把struct Sap *p原来在其他文件里的定义和声明放到main函数前面,也没有实例化,为什么没问题?
而且struct Sap *p在这里只是函数的形参,如何实例化?
1.看看全局函数的相关信息。
2.我只是用了*p这个名字举例而已,你可以用别的名字代替啊。