C语言结构体为何无法赋值?

工程中建立了一个任务函数TcpTest,保存为文件名为TCP.c的文件:structSap*SAP//定义结构体指针voidTcpTest(void){function1... 工程中建立了一个任务函数TcpTest,保存为文件名为TCP.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)为何在另外建的工程中可以正常赋值?

谢谢!
}
展开
 我来答
格里编程办公技巧
科技发烧友

2021-07-30 · 编程、办公知识分享与学习
格里编程办公技巧
采纳数:434 获赞数:879

向TA提问 私信TA
展开全部

问题一:

原任务中SAP是全局指针变量,虽然你没有进行初始化,但是根据编译器对全局变量的原则,所有全局或者静态变量会默认初始化为0(NULL)。如果一个指针被初始化为NULL,那自然是不能对其指向的成员进行赋值,赋值失败。

问题二

接问题一,sap指针变量放在main里就是局部变量,编译器不会对其进行初始化,只分配变量内存,这里说的是指针变量的内存,保留其内存的内容。此时sap里的内容是随机的,也就是说它指向一个随机的内存地址。如果这个随机的地址,不受操作系统保护,那你依然可以进行赋值操作。这就是为啥放在main又可以赋值的原因,但是这个行为是非常危险的,因为用了本不应该属于你的内存,可能改变了其它数据的值,导致你的或者其它的程序不正常。

解决方案:

首先无论是全局还是局部指针变量,养成良好的习惯定义变量是同时初始化为NULL,在你要把它传递给函数时根据函数的需要对其进行真正的初始化,比如题目中是要申请内存。

同时在函数实现的代码中,如果函数要对指针成员进行赋值,那在之前可以对指针进行判断加入,如果是NULL那是不是直接退出提示错误。

if(p == NULL)

{

//没有初始化怎么操作的代码

}

这里会有个坑,如果在if里加入申请内存的代码是没有用的,因为只是改变了形参,实参改变不了,除非用二级指针,调用是传入指针的地址。

百度网友1442c68
2020-12-20 · TA获得超过1083个赞
知道大有可为答主
回答量:4466
采纳率:57%
帮助的人:825万
展开全部
记住定义的结构在使用之前必须实例化,如struct Sap *p=new(struct Sap)这样,否则就是一个空架子,肯定没法赋值。
更多追问追答
追问
请问我另外单独建立了一个工程,把其他的语句全都去掉,只是把struct Sap *p原来在其他文件里的定义和声明放到main函数前面,也没有实例化,为什么没问题?
而且struct Sap *p在这里只是函数的形参,如何实例化?
追答
1.看看全局函数的相关信息。
2.我只是用了*p这个名字举例而已,你可以用别的名字代替啊。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式