我在教一个朋友C。我们正在研究结构和指针,我给了他一个程序,让他在电脑上试用。我们将逐行解构程序,这样他就能理解结构和指针是如何协同工作的。最后,我得到了这样的结果:
a在astr中的值是5
astr中b值为550000
astr中c值为77
astr中d值为888.888800
在他的计算机上,除了最后一个astr->d的值打印出一些非常大的负数外,程序大部分都在工作。所以我的问题是,为什么这件事发生在他的电脑上,而在我的电脑上却很好?下面是违规代码:
#include <stdio.h>
#include <stdlib.h>
int main(){
struct a_struct{
int a;
float b;
int c;
double d;
};
struct a_struct* astr;
astr = (struct a_struct*)malloc(sizeof(astr));
astr->a = 5;
astr->b = 5.55;
astr->c = 77;
astr->d = 888.8888;
printf("Value of a in astr is %d\n", astr->a);
printf("Value of b in astr is %f\n", astr->b);
printf("Value of c in astr is %d\n", astr->c);
printf("Value of d in astr is %lf\n", astr->d);
return 0;
}
最佳答案
你至少有两个问题。
首先,您的malloc
呼叫不正确。
astr = (struct a_struct*)malloc(sizeof(astr));
astr
是指针,因此sizeof(astr)
是指针的大小。您需要分配足够的内存来保存struct astruct
类型的对象。astr = (struct a_struct*)malloc(sizeof (struct a_struct)));
或者,更简单、更有力地说:
astr = malloc(sizeof *astr);
(不计算
sizeof
的参数,因此sizeof *astr
提供astr
指向的内容的大小,而不试图取消对它的引用。转换是不必要的,因为malloc
返回一个void*
,它被隐式转换为所需的指针类型。)其次,您使用了错误的格式,而不是正确的格式来打印
astr->d
。%f
格式对float
和double
参数都有效(因为float
的printf
参数升级为double
)。long double
参数的正确格式是%Lf
。只需对%f
和astr->b
使用astr->d
。(从C99"%lf"
开始相当于%f
,但最好只是使用%f'
)第三(好,我算错了),您应该通过将结果与
malloc
进行比较来检查NULL
调用是否成功。如此小的分配不太可能失败,但坚持检查是一个很好的习惯。如果失败了,您可以用错误消息中止程序(对于较大的程序,可能需要更复杂的错误处理)。