HelloWorld

ASM,C,LUA,LINUX(gentoo)
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

数组名和函数名的一个特征

Posted on 2011-09-29 14:48  光铭  阅读(427)  评论(0编辑  收藏  举报
#include<stdio.h>
void hello(void);
int main(void)
{
	int a[10];
	char *b[10]={
		"hello",
		"world"
	};
	char *c[10];
	printf("%p\t%p\t\n",hello,&hello);
	printf("%p\t%p\t%p\t\n",a,&a,&a[0]);
	printf("%p\t%p\t%p\t%p\t\n",b,&b,b[0],&b[0]);
	printf("%p\t%p\t%p\t\n",c,&c,&c[0]);
	return 0;
}
void hello(void)
{
}

输出

0x40061a        0x40061a
0x7fff3773b7f0  0x7fff3773b7f0  0x7fff3773b7f0
0x7fff3773b7a0  0x7fff3773b7a0  0x40070c        0x7fff3773b7a0
0x7fff3773b750  0x7fff3773b750  0x7fff3773b750

结论:对于函数名和数组名而言

int a[];

a和&a和&a[0]的值都是一样的

void hello(void);

hello和&hello是一样的

这也就是为什么

void ToUpper(char *);
void(*pf)(char *);
pf=ToUpper;//pf=&ToUpper也是可以的
调用的时候(*pf)();和pf();都可以的原因了

对于一个二维数组来讲,有6个值都是一样的
#include<stdio.h>
int main(void)
{
	int b[10][3];
	printf("%p\t%p\t%p\t%p\t%p\t%p\n",b,&b,&b[0],b[0],*b,&b[0][0]);
	return 0;
}
//结果

0x7fff229e2dd0  0x7fff229e2dd0  0x7fff229e2dd0  0x7fff229e2dd0  0x7fff229e2dd0  0x7fff229e2dd0

值虽然一样,但是类型不一样,这点要注意区分

我这里分析以下值为什么会一样

在内存来面如何来定位一个值呢?很简单,地址加值的长度,地址常常由基址加偏移量来确定,而值的长度由值的类型来确定

那么一个值在内存中有时候占的不是一个字节,值的地址是那个字节的地址呢?C语言规定,第一个字节的地址为值的地址。

int a[10];

那么数组的地址(&a)就是数组第一个元素的地址(&a[0])。并且在表达式中数组名(a)退化为一个指针,也指向的是第一个元素的地址(&a[0])

这就是为什么他们的值相等的原因了

但是要注意类型不一样,一定要注意

int (*pa)[10]=&a;

int *pa=a;

一个是指向数组的指针,一个是指向整数的指针。

那我们这里说指向是什么意思呢?

比如说int b;

int *c=&b;

这里才说c是指向b的,就是说指针的值等于所指向的值的地址。

c专家编程213页混淆了这个概念。可能表述不清,或许翻译有误,总之花了我一晚上的时间

来求证这个东西,好在概念更加清晰了。