#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页混淆了这个概念。可能表述不清,或许翻译有误,总之花了我一晚上的时间
来求证这个东西,好在概念更加清晰了。
衣带渐宽终不悔,为伊消得人憔悴