C语言(C99)声明结构体后,给里面加值,printf输出时多加了取地址符结果很奇怪,尝试复盘没想明白。
int main() {
//声明student 结构体
struct student{
int num;char name[20];char sex;
int age;float score;char addr[30];
};
struct student s= {1001,"lele",'M',20,85.4,"Shenzhen"};
//定义一个student类型的结构体s,同时初始化.
struct student sarr[3];
int i;
printf("%d %s %c %d %f %s\n",s.num,s.name,s.sex,s.age,s.score,s.addr);
for(i=0;i<1;i++){
scanf("%d%s %c%d%f%s",&sarr[i].num,&sarr[i].name,&sarr[i].sex,
&sarr[i].age,&sarr[i].score,&sarr[i].addr);
}
for(i=0;i<1;i++){
//下面是错掉的输出代码,为什么会犯错主要是因为复制粘贴了上面的一部分代码偷懒。
printf("%d %s %c %d %f %s\n",&sarr[i].num,&sarr[i].name,&sarr[i].sex,
&sarr[i].age,&sarr[i].score,&sarr[i].addr);
}
return 0;
}
测试用例
1002 Meme M 20 85.419998 SZ
不改动代码的输出结果为
6421760 Meme 6421788 0.000000 SZ
其中在Clion的输出框里显示的是个不认识的占位符
把取地址符全去了改成正确的,输出结果
1002 Meme M 20 85.419998 SZ
说明scanf应该没啥问题。
输出改为
printf("%d %s %c %d %f %s\n",&sarr[i].num,&sarr[i].name,sarr[i].sex,
sarr[i].age,&sarr[i].score,sarr[i].addr);
//保留了.num,.name,.score的取地址符,输出结果下面一行
6421760 Meme M 20 0.000000 SZ
打断点后,发现&sarr[0].num 地址值61FD00,换算十进制刚好就是第一个输出结果6421760,也能拿到输进去的数字。
于是我用*&去看赋值有没有问题,发现赋值都没问题,.name的char数组存好了,.score也存到了输进去的分数。
再进一步我回头去看类型的时候注意到num是int型,&int或许是输出了他的地址,这个可以理解。但name是char型,&sarr[i].name结果输出的不是地址,而是我输进去的测试用例MeMe。&sarr[i].score输出的也不是地址,而是0.00000.
百科试着查了一下取地址符,查出来也就是知道C中&除了取地址还是按位运算的运算符,但还是想不通为什么在这个写错的printf输出里面&sarr[i].num 输出了地址,&sarr[i].name 输出了我想要的值,而&sarr[i].score输出了一个0.0000(可能是真的就按位运算输出了个0)。
猜测是&可能对于不同情况有不同的默认匹配,但是百度也没搜到c语言中的&具体是怎么实现的,求大佬们解惑。
使用printf函数输出结构体成员的值时,是否需要使用取地址符&取决于结构体成员的类型。
对于基本数据类型的成员(如int、float等),直接使用成员名即可,不需要取地址符。而对于数组名(如char数组),数组名本身就表示数组的首地址,也不需要再使用取地址符。
在你的代码中:
正确的方式:
printf("%d %s %c %d %f %s\n", sarr[i].num, sarr[i].name, sarr[i].sex,
sarr[i].age, sarr[i].score, sarr[i].addr);
还是要去深入理解*
与&
。
顺着你的的描述写了这么多,也不知道有不有用。
给你推荐一个很不错的教程 C语言基础教程
主要内容:结构体变量,成员的获取和赋值前面的教程中我们讲解了 数组(Array),它是一组具有相同类型的数据的集合。但在实际的编程过程中,我们往往还需要一组类型不同的数据,例如对于学生信息登记表,姓名为字符串,学号为整数,年龄为整数,所在的学习小组为字符,成绩为小数,因为数据类型不同,显然不能用一个数组来存放。 在C语言中,可以使用 结构体(Struct)来存放一组不同类型的数据。结构体的定义形式为: struct 结构体名{
C++ 运算符 .(点)运算符和 ->(箭头)运算符用于引用类、结构和共用体的成员。 点运算符应用于实际的对象。箭头运算符与一个指向对象的指针一起使用。例如,假设有下面的结构: struct Employee { char first_name[16]; int age; } emp; (.)点运算符 下面的代码把值 "zara" 赋给对象 emp 的 first_name 成员:
运算符和表达式 运算符 C语言的运算范围很宽,把除了控制语句和输入/输出以外的几乎所有的基本操作都作为运算符处理。运算符主要分为三大类:算术运算符、关系逻辑运算符、按位运算符。根据运算符的运算对象的个数,C语言的运算符又可分成单目运算符、双目运算符、三目运算符。运算符具体分类情况如下表所示: C语言运算符 分类名称 运算符 算术运算符 +、-、*、/、% 关系运算符 <、>、<=、>=、==、!=
主要内容:获取结构体成员,结构体指针作为函数参数当一个 指针变量指向结构体时,我们就称它为 结构体指针。 C语言结构体指针的定义形式一般为: struct 结构体名 *变量名; 下面是一个定义结构体指针的实例: 也可以在定义结构体的同时定义结构体指针: 注意,结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必须在前面加 ,所以给 pstu 赋
所谓 结构体数组,是指数组中的每个元素都是一个结构体。在实际应用中, C语言结构体数组常被用来表示一个拥有相同 数据结构的群体,比如一个班的学生、一个车间的职工等。 在C语言中,定义结构体数组和定义结构体变量的方式类似,请看下面的例子: 表示一个班级有5个学生。 结构体数组在定义的同时也可以初始化,例如: 当对数组中全部元素赋值时,也可不给出数组长度,例如: 结构体数组的使用也很简单,例如,获取
本文向大家介绍简单总结C语言中的运算符优先级,包括了简单总结C语言中的运算符优先级的使用技巧和注意事项,需要的朋友参考一下 C语言中有很多运算符,除了四则运算,还有位运算、比较运算、逻辑运算、赋值运算等等,令人眼花缭乱的同时,优先级也让人头疼。通常建议在写代码的时候不用省略括号,但是并不是所有程序员都会按照这个规矩来,因此还是有必要记录一下,以备查阅。 总结几个比较重要的原则: 取成员的“0”目运