给出以下代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[1];
int * b = malloc(sizeof(int));
/* 1 */
scanf("%d", &a);
printf("%d\n", a[0]);
/* 2 */
scanf("%d", &b);
printf("%d\n", b[0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译时获得以下警告(i686-apple-darwin9-gcc-4.0.1):
array.c: In function 'main':
array.c:9: warning: format '%d' expects type 'int *', but argument 2 has type 'int (*)[0u]'
array.c:14: warning: format '%d' expects type 'int *', but argument 2 has type 'int **'
Run Code Online (Sandbox Code Playgroud)
但是,为什么在第二个printf中发生执行错误,同时它适用于第一个printf?
更重要的是,如果用scanf代替第一个scanf("%d",a),为什么得到相同的输出; ?
非常感谢提前
Joh*_*ode 10
在大多数情况下,数组类型的表达式将从"N元素数组T"隐式转换为"指向T",其值将设置为指向数组的第一个元素.此规则的例外情况是当数组是&或sizeof运算符的操作数时,或者数组是用于初始化声明中的另一个数组的字符串文字.
那么所有与你的代码有什么关系呢?
在线
scanf("%d", &a);
Run Code Online (Sandbox Code Playgroud)
您正在将&运算符应用于数组.这抑制了从"T的数组"到"指向T的指针"的隐式转换,并返回类型为"指向T的数组的指针"的值,或者T (*)[N](因此是您的第一个警告).现在事实证明,指向数组的指针的值和指向数组的第一个元素的指针的值是相同的,它们只是具有不同的类型.所以假设它a在地址0x0001000:
expression type value note
---------- ---- ----- ----
a int * 0x0001000 implicitly converted to pointer
&a int (*)[N] 0x0001000
&a[0] int * 0x0001000
Run Code Online (Sandbox Code Playgroud)
这就是你第一次打电话给scanf()"工作"的原因; 你正在传递正确的指针值,但编译器抱怨,因为表达式的类型与函数所期望的不匹配.如果你写的
scanf("%d", a);
Run Code Online (Sandbox Code Playgroud)
你不会收到任何警告,因为a将会采取类型int *,这是scanf()预期的.请注意,这与呼叫相同
scanf("%d", &a[0]);
Run Code Online (Sandbox Code Playgroud)
至于b......
您显式声明b为指向int的指针并为其分配一块内存.当你&对它应用运算符时,你得到的是带有类型的变量 的地址(因此是第二个警告),而不是指向的地址. bint **b
expression type value note
---------- ---- ----- ----
b int * 0x0040000 value contained in b
&b int ** 0x0001000 address of b
Run Code Online (Sandbox Code Playgroud)
对于这种情况,你只需通过未修饰的b:
scanf("%d", b);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5358 次 |
| 最近记录: |