Scanf的困惑
在學習“鳥叔”的Linux教程時碰到了一個奇怪的事情。例程給的代碼如下:
#include <stdio.h>
#define pi 3.14159
char name[15];
float angle;
void haha(char name[]);
int main(void)
{
printf ("\n\nPlease input your name: ");
scanf ("%s", &name );
printf ("\nPlease enter the degree angle (ex> 90): " );
scanf ("%f", &angle );
haha( name );
}
看起來沒什麼問題,但編譯時會報如下錯誤:
main.c:12:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[15]’ [-Wformat=]
scanf ("%s", &name );
大概就是說scanf的參數類型不對,但字符串不是這樣輸入的嗎?
在網上看了一下,正確的方法好像是 scanf(“%s”,name)。修改之後,果然沒警告了。回想一下,當時在有警告的情況下編譯也是通過的,而且程序運行正常,那麼這個name和&name到底有什麼區別?
數組名的含義
這是數組的定義:
char name[15];
name 是數組名,作爲變量,name也是數組的首地址,也就是0xXXXXXXX。。。的東西。
& 是取地址符合,從字面上的意思來看,&name是取數組首地址的地址。兩者有什麼關聯?通過下面這個程序看一下:
#include <stdio.h>
int main(void)
{
int name[10]={0};
int *p=name,*q=&name;
printf("%p,%p\n",p,q);
}
運行後輸出結果如下:
root@obama-ubuntu:/home/obama/project/main# ./main
0x7fff5abfcd20,0x7fff5abfcd20
也就是說兩者的值是一樣的,對於scanf來說,兩者是等價的。
不過對於name[]這個數組來說,意義卻又不一樣。
name[],name,&name
運行如下代碼:
#include <stdio.h>
int main(void)
{
int name[10]={0};
int *p=name+1,*q=&name+1;
printf("%p,%p\n",p,q);
}
我在把name和&name賦值給指針之前,各給其加1,按照常理,相當於到了name[1]的地址,然而結果如下:
root@obama-ubuntu:/home/obama/project/main# ./main
0x7ffed1023714,0x7ffed1023738
0x7ffed1023710應該是數組的地址,0x7ffed1023714是name[1]的地址,那0x7ffed1023738呢?
數組name[10]長度是10,系統的一個整數佔4個字節,所以
0x7ffed1023738 = 0x7ffed1023710 + 40字節 = 0x7ffed1023710 + 10個整形變量
由此可以看出&name+1實際上是name[10]這個整個數組的地址加上了整個數組的長度。不知道官方語言該怎麼說,既然name叫name[10]的首地址,乾脆就叫&name爲name[10]的數組地址吧!