你如何使用 scanf 在 C 中获取一个 int?
How do you use scanf to get an int in C?
我正在尝试了解从控制台获取输入的不同方式的优点和缺点。我对 scanf
感到困惑。为什么我需要使用 &favNumber
而不是 favNumber
?
我理解&favNumber
是favNumber
的地址位置,但是为什么要这样呢?
我觉得这里存在类型不匹配,其中 favNumber
是一个 int,而我告诉 scanf
它是一个指向 int 的指针。我以为我全神贯注于指针,但这让我有点困惑。任何帮助,将不胜感激。谢谢!
#include <stdio.h>
int main()
{
char userPrompt[100] = "What is your favorite number?";
int favNumber;
printf("%s", userPrompt);
scanf("%d", &favNumber);
printf("%d", favNumber);
return 0;
}
当您按值调用函数时,函数会获得参数的副本。对函数中参数的任何更改都不会影响原始变量的值。
void foo(int i )
{
i = 20; // The change is local to the function.
}
void bar()
{
int i = 10;
foo(i);
printf("i=%d\n", i); // i is still 10.
}
如果你想让一个函数改变一个变量的值,函数必须使用指针类型并且调用函数在调用函数时必须使用变量的地址。
void foo(int* i )
{
*i = 20; // The change is visible in the calling function
}
void bar()
{
int i = 10;
foo(&i);
printf("i=%d\n", i); // i is now 20.
}
这就是为什么 scanf
需要指针并且调用函数在调用 scanf
时必须使用变量地址的原因。 scanf
必须能够设置变量的值。
好的,我相信您会感到困惑的是,“&”表示地址,而不是指向地址的指针,因为“*”表示地址本身。您要告诉扫描函数它将在哪里存储从用户那里收到的值。
如果您要引用变量本身,即 'favNumber',您如何知道将您放入标准输入的值存储在哪里? favNumber 只是一个容器,没什么特别的,只是内存中分配用于保存所述字节数的一个位置。我觉得好像我明白你的问题是从哪里来的,但如果你已经遇到过指示,我想你可能会混淆这两者。指针指向内存中的地址,'&' 表示实际地址,大致执行指针的操作,但指向非指针变量。
如果 favNumber 是 'int *' 类型,那么您将不需要 & 符号,因为它已经是一个地址,但您需要取消引用该地址才能知道其中的内容。这大致就是你在 favNumber 中所拥有的,一个取消引用的地址指针,它显示了存储在 favNumber 地址中的内容,它是在程序开始时分配的 运行,在堆栈中。
"How do you use scanf to get an int in C?"
– 你不知道。您使用更明智的方法(例如 fgets()
+ strtol()
),因为 scanf()
古怪笨拙且难以正确使用。
但是,您的问题显然与此无关;你问为什么你必须写 scanf("%d", &favNumber);
当 &favNumber
是一个 int *
但 %d
指定一个 int
.
好吧,您似乎混淆了类型 safety/type 不匹配与库函数期望的类型的任意表示。
&favNumber
是确实是一个指向int的指针。但是,%d
说明符 NOT 表示 "you must pass an int
for this argument"。 %d
是一个库定义的符号,告诉 scanf()
扫描一个整数,并将其放入下一个参数。为了 scanf()
能够修改你的参数,你需要传递一个指向它的指针,实际上这个函数需要你传递一个指向它的指针。
我可以这样说:"%d"
与 printf()
和 scanf()
一起使用时只是意味着不同的东西:在前一种情况下,这意味着你传递了一个 int
参数,在后一种情况下,这意味着您应该传递一个 int *
.
同样,这是因为这些格式字符串 没有内在语义。 格式化的 input/output 函数解释它们——在这种情况下,它们解释格式出于技术必要性原因,字符串有所不同。
&
符号用于通过其内存地址引用一个值。因此,当引用被传递时,该引用的使用会修改引用所在地址的值。
scanf
基本上只是一个函数,如果您熟悉函数,您会看到按值传递给函数的参数对于函数来说是局部的,对它的任何赋值只会改变它的值函数内的值(这不满足在传递的变量中存储 "scanned" 值的需要)。在 scanf
的情况下,它接受一个引用(换句话说,该值在内存中的位置),因此它可以修改该位置的值,并且 "scaned" 值可以存储在感兴趣的变量中。
所以总结一下 &favNumber
所做的就是传递给 scanf
favNumber
变量的内存地址,它本身就是一个 int
,所以一个 int
值然后被写入该地址并且可以通过 favNumber
.
访问
我正在尝试了解从控制台获取输入的不同方式的优点和缺点。我对 scanf
感到困惑。为什么我需要使用 &favNumber
而不是 favNumber
?
我理解&favNumber
是favNumber
的地址位置,但是为什么要这样呢?
我觉得这里存在类型不匹配,其中 favNumber
是一个 int,而我告诉 scanf
它是一个指向 int 的指针。我以为我全神贯注于指针,但这让我有点困惑。任何帮助,将不胜感激。谢谢!
#include <stdio.h>
int main()
{
char userPrompt[100] = "What is your favorite number?";
int favNumber;
printf("%s", userPrompt);
scanf("%d", &favNumber);
printf("%d", favNumber);
return 0;
}
当您按值调用函数时,函数会获得参数的副本。对函数中参数的任何更改都不会影响原始变量的值。
void foo(int i )
{
i = 20; // The change is local to the function.
}
void bar()
{
int i = 10;
foo(i);
printf("i=%d\n", i); // i is still 10.
}
如果你想让一个函数改变一个变量的值,函数必须使用指针类型并且调用函数在调用函数时必须使用变量的地址。
void foo(int* i )
{
*i = 20; // The change is visible in the calling function
}
void bar()
{
int i = 10;
foo(&i);
printf("i=%d\n", i); // i is now 20.
}
这就是为什么 scanf
需要指针并且调用函数在调用 scanf
时必须使用变量地址的原因。 scanf
必须能够设置变量的值。
好的,我相信您会感到困惑的是,“&”表示地址,而不是指向地址的指针,因为“*”表示地址本身。您要告诉扫描函数它将在哪里存储从用户那里收到的值。 如果您要引用变量本身,即 'favNumber',您如何知道将您放入标准输入的值存储在哪里? favNumber 只是一个容器,没什么特别的,只是内存中分配用于保存所述字节数的一个位置。我觉得好像我明白你的问题是从哪里来的,但如果你已经遇到过指示,我想你可能会混淆这两者。指针指向内存中的地址,'&' 表示实际地址,大致执行指针的操作,但指向非指针变量。 如果 favNumber 是 'int *' 类型,那么您将不需要 & 符号,因为它已经是一个地址,但您需要取消引用该地址才能知道其中的内容。这大致就是你在 favNumber 中所拥有的,一个取消引用的地址指针,它显示了存储在 favNumber 地址中的内容,它是在程序开始时分配的 运行,在堆栈中。
"How do you use scanf to get an int in C?"
– 你不知道。您使用更明智的方法(例如 fgets()
+ strtol()
),因为 scanf()
古怪笨拙且难以正确使用。
但是,您的问题显然与此无关;你问为什么你必须写 scanf("%d", &favNumber);
当 &favNumber
是一个 int *
但 %d
指定一个 int
.
好吧,您似乎混淆了类型 safety/type 不匹配与库函数期望的类型的任意表示。
&favNumber
是确实是一个指向int的指针。但是,%d
说明符 NOT 表示 "you must pass an int
for this argument"。 %d
是一个库定义的符号,告诉 scanf()
扫描一个整数,并将其放入下一个参数。为了 scanf()
能够修改你的参数,你需要传递一个指向它的指针,实际上这个函数需要你传递一个指向它的指针。
我可以这样说:"%d"
与 printf()
和 scanf()
一起使用时只是意味着不同的东西:在前一种情况下,这意味着你传递了一个 int
参数,在后一种情况下,这意味着您应该传递一个 int *
.
同样,这是因为这些格式字符串 没有内在语义。 格式化的 input/output 函数解释它们——在这种情况下,它们解释格式出于技术必要性原因,字符串有所不同。
&
符号用于通过其内存地址引用一个值。因此,当引用被传递时,该引用的使用会修改引用所在地址的值。
scanf
基本上只是一个函数,如果您熟悉函数,您会看到按值传递给函数的参数对于函数来说是局部的,对它的任何赋值只会改变它的值函数内的值(这不满足在传递的变量中存储 "scanned" 值的需要)。在 scanf
的情况下,它接受一个引用(换句话说,该值在内存中的位置),因此它可以修改该位置的值,并且 "scaned" 值可以存储在感兴趣的变量中。
所以总结一下 &favNumber
所做的就是传递给 scanf
favNumber
变量的内存地址,它本身就是一个 int
,所以一个 int
值然后被写入该地址并且可以通过 favNumber
.