写我的第一个C程序,我就能';我无法摆脱这只愚蠢的虫子
我使用xCode是因为我发现调试器非常有用。因此,在调试器中,输入学生名称[0]=\0后,无论发生什么情况,我都会看到。但是剩下的名字是正确的。例如,如果我把John放进去,它会回来说\0,o,h,n。请帮忙写我的第一个C程序,我就能';我无法摆脱这只愚蠢的虫子,c,scanf,C,Scanf,我使用xCode是因为我发现调试器非常有用。因此,在调试器中,输入学生名称[0]=\0后,无论发生什么情况,我都会看到。但是剩下的名字是正确的。例如,如果我把John放进去,它会回来说\0,o,h,n。请帮忙 char name[MAX_NAME_LENGTH]; char department[MAX_DEPT_LENGTH]; int rank; int empty = 0; printf("\nPlease
char name[MAX_NAME_LENGTH];
char department[MAX_DEPT_LENGTH];
int rank;
int empty = 0;
printf("\nPlease enter the students name: ");
scanf("%s", &name);
printf("\nPlease enter the students department: ");
scanf("%s", &department);
printf("\nPlease enter the students rank: ");
scanf("%d", &rank);
strcpy(studentArray[empty].name, name);
strcpy(studentArray[empty].department, department);
studentArray[empty].rank = rank;
这样做:
printf("\nPlease enter the students name: ");
scanf("%s", name);
printf("\nPlease enter the students department: ");
scanf("%s", department);
printf("\nPlease enter the students rank: ");
scanf("%d", &rank);
请注意,在对scanf
的前两次调用中,没有使用符号AND。这是因为在表达式中使用name
和department
时,编译器会隐式地将它们转换为指向相应数组的第一个元素(&name[0]
,&department[0]
)的指针(此规则存在预期,有关详细信息,请参阅)
阅读以供进一步参考。使用scanf(“%s”,名称)代码>
避免使用&,它太容易出错。您的变量name
和department
是字符数组(char(*)[]
)。当您将这些变量传递给printf/scanf(或任何其他函数,数组通过引用传递)时,它们的类型将衰减为TYPE*
(在您的示例中为char*
),并作为数组中第一个元素的内存位置传递
当您尝试传递变量的地址(&name
)时,您传递的是指向该变量内存位置的指针(在您的情况下,该指针衰减为char(*)[0]
)。这个问题引起了我的兴趣,因为name
和&name
将具有相同的值,但类型不同。由于printf/scanf被定义为接收char*
,因此传递char(*)[]会导致未定义的行为-一些编译器会为您处理if,而其他编译器则不会(VS2010或更早版本可能会为您处理)
我很接近,但在这个答案上得到了一些帮助(学到了很多):。如果他们在这里提供答案,我将删除我的。您需要使用scanf(“%s”,name)代码>而不是scanf(“%s”、&name)代码>(与部门相同)
scanf
需要写入的内存地址。对于字符串,它需要一个char*
,在这种情况下传递char[]
是可以的(它很容易发生缓冲区溢出!)
但是,对于不是指针的整数,您需要传递整数的内存地址,即&rank
,而不是您已经传递的rank
。scanf函数需要知道它需要读入的内存地址,因此对于整数之类的东西
scanf("%d", &rank);
这是正确的。但名称等内容已经是地址(数组的名称实际上是其第一个元素的地址),因此:
scanf("%s", &name);
你想要:
scanf("%s", name);
对于其他数组也是如此。当您声明数组时
char name[MAX_NAME_LENGTH];
name
不带索引是指向数组中第一个元素的指针
name == &name[0]
当函数(如scanf()
)调用char*
时,它需要指向第一个元素的指针
scanf("%s", name);
你能把studentArray的声明也说出来吗?离题(你的问题是你在应该说名字的地方使用了&name
),但是scanf
和%s
是不好的时候。您不需要指定缓冲区大小,这意味着用户可以输入一个比缓冲区长的字符串并粉碎堆栈。有一个不可移植的扩展名%a
,它将为您分配适当的内存量,但在我看来,最好是完全避免scanf
糟糕的界面。您确定这就是您的全部代码吗?你能给出一个完整的、可编译的例子来说明这个问题吗?(我没有xCode或Mac,但我无法用六种编译器和设置组合重现这种行为。)&rank
完全正确。除此之外,给初学者一个简短的解释是合适的。是的,很抱歉。我喜欢这样想:没有真正的数组,只有内存、指针和偏移量。如果从一开始就这样教我,我可能会避免在我以前的课程中犯一些愚蠢的错误。@Grigory不幸的是,事实并非如此。很好,它对你有用。。。但是有数组,它们与指针非常不同。看见以及第6节中的所有其他问题。当使用&
写入整数时,完全可以。实际上,这是必要的。“避免使用&
”?真正地如果在用C语言编程时避免使用安培兰,则不会有太大进展。“name
没有索引是指针。”除非没有索引:对于长度大于1的数组,sizeof(name)!=sizeof(&name[0])
name
始终是一个数组;在大多数情况下,它只是隐式转换为指向其初始元素的指针。