我是C编程语言的新手。现在我正在学习记忆和指针。我正在阅读和阅读,但我不知道何时使用指针,何时不使用。只需看下面的代码即可。在我的第一个代码中,为什么我们不使用“&”此行上的运算符“scanf(”%2s“,card_name)”?以及我的第二个代码为什么我必须使用“&”操作员在我的“scanf(”%i“,& decks);” 我整夜都明白了。现在我来这里得到一些好的提示,以了解其中的差异..
代码1
#include <stdio.h>
#include <stdlib.h>
int main(){
char card_name[3];
int count=0;
while (card_name[0]!='X') {
int val=0;
puts("Enter The Card Name:");
scanf("%2s", card_name);
switch (card_name[0]) {
case 'K':
case 'Q':
case 'J':
val=10;
break;
case 'A':
val=11;
break;
case 'X':
continue;
default:
val= atoi(card_name);
break;
}
if (val<2||val>11) {
puts("sorry this is not valid");
break;
}
if (val>=2&&val<=10) {
count++;
printf("Then value is %i And The Count is %i\n", val, count);
break;
}
}
}
}
代码2
#include <stdio.h>
int main() {
int decks;
puts("Enter a number of decks");
scanf("%i", &decks);
if (decks < 1) {
puts("That is not a valid number of decks");
return 1; }
printf("There are %i cards\n", (decks * 52));
return 0;
}
答案 0 :(得分:6)
你偶然发现的可能是关于C语言最微妙的事情:数组标识符衰减成指针的事实。当你写
char card_name[3];
定义一个包含三个字符的数组。这很简单,card_name
的类型写为char ()[3]
。
难以理解的是,card_name
几乎在所有上下文中都会衰减到指向该数组的第一个元素的指针,因此几乎所有提及card_name
的类型都将是{{} 1}}。 几乎就像地址获取运算符被隐含地应用于任何提及的数组名称一样。因此,当您将char*
传递给card_name
时,您实际上是将指针传递给它的第一个元素,而scanf()
使用此指针来存储名称。
另一方面,当你用整数做同样的事情时,没有像指针衰减这样的东西。代码的行为完全符合您的预期,每当您使用名称scanf()
时,您将获得整数的值,而不仅仅是其地址。这就是为什么你必须明确地从decks
获取地址。
答案 1 :(得分:1)
尝试理解间接的指针级别。 Scanf总是将1级指针作为争论。
声明了一个数组:
char name[4];
和name是1级对象。当作为argement传递时,数组衰减为指针:
void f(char* name) { ... }
其他1级对象:
int* p1;
double* d1;
这些是第2级对象:
int** p2;
double** d2;
和等级0:
int p0;
double d0;
因此,级别是声明中的星号(或[])的数量。 这可以通过使用*和&amp;来在代码中进行修改。 *取消引用指针并将级别降低1.但是&amp;反之亦然 - 它将等级提高1。
因此,使用上面的scanf,我们将:
scanf("%i%i%i", &p0, p1, *p2);
scanf("%lf%lf%lf", &d0, d1, *d2);
其中 &amp; p0为0 + 1为&amp;共1个 p1已经是1 * p2为2级 - 1代表*总共1