數組的首地址與數組的首地址取地址

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]的數組地址吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章