数组的首地址与数组的首地址取地址

来源:互联网 发布:2016年好听的网络歌曲 编辑:程序博客网 时间:2024/06/06 00:23

Scanf的困惑

在学习“鸟叔”的Linux教程时碰到了一个奇怪的事情。例程给的代码如下:
#include <stdio.h>#define pi 3.14159char 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]的数组地址吧!

0 0
原创粉丝点击