dba*_*osa 15 c gcc pointers addressof
我是入门编程课程的助教,有些学生犯了这种错误:
char name[20];
scanf("%s",&name);
Run Code Online (Sandbox Code Playgroud)
这并不奇怪,因为他们正在学习......令人惊讶的是,除了gcc警告之外,代码也起作用(至少这部分).我一直在努力理解并编写了以下代码:
void foo(int *v1, int *v2) {
if (v1 == v2)
printf("Both pointers are the same\n");
else
printf("They are not the same\n");
}
int main() {
int test[50];
foo(&test, test);
if (&test == test)
printf("Both pointers are the same\n");
else
printf("They are not the same\n");
}
Run Code Online (Sandbox Code Playgroud)
编译和执行:
$ gcc test.c -g
test.c: In function ‘main’:
test.c:12: warning: passing argument 1 of ‘foo’ from incompatible pointer type
test.c:13: warning: comparison of distinct pointer types lacks a cast
$ ./a.out
Both pointers are the same
Both pointers are the same
Run Code Online (Sandbox Code Playgroud)
谁能解释为什么他们没有什么不同?
我怀疑是因为我无法获取数组的地址(因为我不能拥有& &x
),但在这种情况下代码不应该编译.
编辑:我知道数组本身与第一个元素的地址相同,但我认为这与此问题无关.例如:
int main() {
int a[50];
int * p = a;
printf("%d %d %d\n", p == a, p == &a[0], &p[0] == a);
printf("%d %d %d\n", p == &a, &p == a, &p == &a);
}
Run Code Online (Sandbox Code Playgroud)
打印:
$ ./a.out
1 1 1
1 0 0
Run Code Online (Sandbox Code Playgroud)
我不明白为什么第二行开头1
.
caf*_*caf 24
在您的示例中,数组test
是50的块ints
.所以它看起来像这样:
| int | int | ... | int |
Run Code Online (Sandbox Code Playgroud)
将一元运算&
符应用于数组时,将获得该数组的地址.就像你将它应用于其他任何东西一样,真的.所以&test
是一个指向50块的指针ints
:
(&test) -----------> | int | int | ... | int |
Run Code Online (Sandbox Code Playgroud)
指向50个int的数组的指针具有类型int (*)[50]
- 这是类型&test
.
当你test
在任何不是或者是一sizeof
元&
运算符的操作数的地方使用这个名字时,它会被评估为指向它的第一个元素的指针.所以test
你传递给它的foo()
是一个指向test[0]
元素的指针:
(test) -----------------\
v
(&test) -----------> | int | int | ... | int |
Run Code Online (Sandbox Code Playgroud)
您可以看到这两者都指向相同的地址 - 虽然&test
指向整个数组,并且test
指向数组的第一个元素(仅显示这些值具有的不同类型).
实际上,它们是不同的,它们至少没有相同的类型.
但是在C中,数组的地址与数组中第一个元素的地址相同,这就是为什么"它们没有不同",基本上,它们指向同一个东西.
如果你定义一个像这样的数组
char name[20];
Run Code Online (Sandbox Code Playgroud)
name
可隐式转换为char*
,但&name
属于类型char (*)[20]
(指向20个字符的数组的指针).地址是一样的.
检查地址(&name + 1)
.它不同于形式&name
通过 sizeof(char [20])
.