请原谅我的英语,我的程序按原样崩溃,但是当我将结构成员*name
(字符串)更改为name[50]
并删除命令时(students+i)->name = (char*)malloc(50 * sizeof(char));
程序工作正常,所以我想问题是我在为每个名称动态分配内存时做错了什么。
#include <stdio.h>
#include <stdlib.h>
struct student
{
char *name;
int grade;
};
int main()
{
int student_number = 0,i;
struct student *students = NULL;
printf("Give the number of students: ");
scanf("%d",&student_number);
students = (struct student*)malloc(student_number * sizeof(struct student));
for(i=0;i<student_number;i++)
{
(students+i)->name = (char*)malloc(50 * sizeof(char));
system("CLS");
printf("Give the name of student no. %d: ",i+1);
scanf(" %s",&(students+i)->name);
printf("Give the grade of student no. %d: ",i+1);
scanf("%d",&(students+i)->grade);
}
system("CLS");
for(i=0;i<student_number;i++)
{
printf("%d. %s %dn",i+1,(students+i)->name,(students+i)->grade);
}
system("PAUSE");
return 0;
}
调用 Cscanf
函数的一些正确方法是:
scanf("%d", int*)
scanf("%s", char*)
这是不正确的:
scanf("%s", char**)
考虑工作代码:
int grade;
char name [50];
scanf("%d", &grade);
scanf("%s", name);
这里grade
是一个int
变量,所以&grade
是指向int
变量的指针,类型为int*
。所以这是正确的。
name
是一个char
数组,当传递给scanf
时,它会衰减到指向数组第一个元素的char
指针(类型char*
)。所以这也是正确的。
char name [50];
scanf("%s", &name);
&name
是指向50
char
数组的指针,类型为char(*)[50]
,因此从技术上讲这是不正确的,但它恰好有效,因为指针的值与&name[0]
或(char*) name
相同。
struct a { int x; int y; };
a b;
scanf("%d", &b);
这段代码也是错误的,但碰巧有效,因为&b
具有与&b.x
相同的值(大多数时候),因此代码将具有与
scanf("%d", &b.x);
尽管指针类型不同。无论如何,不要依赖行为。
int grade;
scanf("%d", grade);
这崩溃grade
因为不是指向int
的指针。
现在考虑动态分配的数组(当然,记住在使用完后调用free(name)
)。
char* name;
name = (char*) malloc(50 * sizeof(char));
请考虑改用calloc
。但无论如何,在这种情况下,name
是一个指向已分配内存的第一个字节的char
指针。所以
scanf("%s", name)
是正确的,因为name
是指向分配内存的char*
,正如我上面所说。
scanf("%s", &name)
&name
是指向字符指针name
的指针,类型为char**
。不對。
总之,明智地使用&
。不要坚持模式scanf("format", &variables)
.
不相关的说明:不要使用(students+i)->name
,请改用students[i].name
。它更清楚了。
首先,删除 scanf(" %s" &(students+i)->name) 中的 '&' 这是因为它已经是一个指针,当它只要求一个指针时,"&"使它成为指向指针的指针。添加此更改后,它对我来说效果很好。