但是,不要忽视 编译器警告,它们是为了帮助你,而不是打扰你 void input(char *a) { scanf("%s", a); }
将是正确的函数 做 是错误的,即使但是,不要忽视 编译器警告,它们是为了帮助你,而不是打扰你 void input(char *a) { scanf("%s", a); },c,C,将是正确的函数 做 是错误的,即使名称和名称的地址相同,但是 它们将有不同的类型名称衰减为指针,因此它是一个 char*。但是,&name是指向另一种类型的字符数组的指针。 编译器应向您发出如下警告: 警告:从不兼容的指针类型传递bar的参数1 注意:应为char*,但参数的类型为char(*)[8] 正确的呼叫是: input(name); 但总的来说,有一个大问题:只为 缓冲器如果名称超过7个字符,您将有一个缓冲区 溢流我建议不要使用scanf而是使用fgets,因为 在这里,您可以更好地
名称
和名称
的地址相同,但是
它们将有不同的类型<代码>名称衰减为指针,因此它是一个
char*
。但是,&name
是指向另一种类型的字符数组的指针。
编译器应向您发出如下警告:
警告:从不兼容的指针类型传递bar
的参数1
注意:应为char*
,但参数的类型为char(*)[8]
正确的呼叫是:
input(name);
但总的来说,有一个大问题:只为
缓冲器如果名称超过7个字符,您将有一个缓冲区
溢流我建议不要使用scanf
而是使用fgets
,因为
在这里,您可以更好地控制输入和内存边界
char name[30];
fgets(name, sizeof(name), stdin);
name[strcspn(name, "\n")] = 0; // removing possible newline
scanf
并不总是易于使用。名称可以很长,并且可以包含空格。
特别是对于初学者来说,这可能很棘手<代码>fgets
更易于使用。此功能存在问题:
void input(char* a)
{
char buff[8];
scanf("%s", buff);
*a = buff;
}
buff
是局部变量,仅在运行input()
时有效,因此
返回此变量是错误的
*a=buff代码>也是错误的*a
与a[0]
相同,这意味着它是一个
char
buff
是一个字符数组,因此您要为数组分配一个指针
将char
转换为char
变量。听起来不对,这是在放苹果
橘子盒子。事实上,您正在分配地址
由a
指向的内存中的buff
指向。
你的编译器应该警告你这一点,不要忽略
编译器警告,它们是为了帮助你,而不是打扰你
void input(char *a)
{
scanf("%s", a);
}
将是正确的函数
做
是错误的,即使名称
和名称
的地址相同,但是
它们将有不同的类型<代码>名称
衰减为指针,因此它是一个
char*
。但是,&name
是指向另一种类型的字符数组的指针。
编译器应向您发出如下警告:
警告:从不兼容的指针类型传递bar
的参数1
注意:应为char*
,但参数的类型为char(*)[8]
正确的呼叫是:
input(name);
但总的来说,有一个大问题:只为
缓冲器如果名称超过7个字符,您将有一个缓冲区
溢流我建议不要使用scanf
而是使用fgets
,因为
在这里,您可以更好地控制输入和内存边界
char name[30];
fgets(name, sizeof(name), stdin);
name[strcspn(name, "\n")] = 0; // removing possible newline
scanf
并不总是易于使用。名称可以很长,并且可以包含空格。
特别是对于初学者来说,这可能很棘手fgets
更容易使用。你陷入了一个典型的新手错误——试图在函数外部使用局部函数(*a=buff;
不会复制字符串!)@YePhIcK那么正确的方法是什么呢?也许使用双指针(<代码>空洞输入(char **);< /COD> >),在这里所说的其他所有东西之上,考虑使buff / name数组大于8。也许10-20。它可能是未来bug和问题的来源。我自己的名字比这个长:)一个8字节的缓冲区是自找麻烦scanf
正在自找麻烦。很多这只是麻烦。在可以限制从输入读取数据量的位置使用scanf
如果数据不合适,可能会爆炸。你陷入了一个典型的新手错误——试图在函数外部使用局部函数(*a=buff;
不会复制字符串!)@YePhIcK那么正确的方法是什么?也许使用双指针(<代码>空洞输入(char **);< /COD> >),在这里所说的其他所有东西之上,考虑使buff / name数组大于8。也许10-20。它可能是未来bug和问题的来源。我自己的名字比这个长:)一个8字节的缓冲区是自找麻烦scanf
正在自找麻烦。很多这只是麻烦。在可以限制从输入读取数据量的位置使用<如果数据不合适,代码>扫描可以并且将爆炸。我的编译器实际上发出警告。老实说,我从来没有见过main(void)这个概念,包括在很多书和网上。@atruintmain(void)
是三种可能的“main”组合之一。如果编译器对此发出警告,则说明编译器有问题。你在使用哪种编译器?@Pablo我知道了,我只是在质疑int main(void)的必要性以及它比int main()的优越性。第三种方法不使用参数也没有多大意义。不幸的是,发出了叮当声,但我很确定我也只在gcc上收到了警告。intfoo()之间的区别
和int-bar(void)
是您可以将参数传递给foo
,使用bar
编译器将不允许您传递参数。我的编译器实际上发出警告。老实说,我从来没有见过main(void)这个概念,包括在很多书和网上。@atruintmain(void)
是三种可能的“main”组合之一。如果编译器对此发出警告,则说明编译器有问题。你在使用哪种编译器?@Pablo我知道了,我只是在质疑int main(void)的必要性以及它比int main()的优越性。第三种方法不使用参数也没有多大意义。不幸的是,发出了叮当声,但我很确定我也只在gcc上收到了警告。intfoo()之间的区别
和int-bar(void)
是您可以将参数传递给foo
,使用bar
编译器将不允许您传递参数
void input(char* a)
{
char buff[8];
scanf("%s", buff);
*a = buff;
}
void input(char *a)
{
scanf("%s", a);
}
char name[8];
input(&name);
input(name);
char name[30];
fgets(name, sizeof(name), stdin);
name[strcspn(name, "\n")] = 0; // removing possible newline