首先看下如下代码,猜猜看会输出什么?数组
#include <stdio.h> int main() { char s[] = "How big is it?"; char *t = s; printf("%lu\n", sizeof(s)); printf("%lu\n", sizeof(t)); printf("%p\n", s); printf("%p\n", t); printf("%p\n", &s); printf("%p\n", &t); return 0; }
output:指针
15 8 0x7fff5ab94af5 0x7fff5ab94af5 0x7fff5ab94af5 0x7fff5ab94ae8
这个时候咱们看到 printf("%p\n", s)
和 printf("%p\n", t)
返回了一样的值,也就是数组变量s[]的第一个元素的指针地址。记住数组变量能够被看成指针使用,它指向数组在存储器中的起始地址。code
既然这样有些小伙伴可能会惊呆了,那为何 printf("%lu\n", sizeof(s))
会返回15即字符串的真实长度而不是数组起始地址的指针长度?这里有个特性是 sizeof()运算符
针对这种状况会自动开窍,若是你传给它一个数组变量则会返回字符串的实际长度。若是你使用 sizeof(&s)
那返回的就是指针的长度了,在64位OSX下返回的数值则是8。至于 printf("%lu\n", sizeof(t))
上面已经进行了 char *t = s
的赋值操做,其实 t
如今骨子里已经存放了数组变量 s
首位元素的指针地址。sizeof
对此就只会输出实际的指针地址长度,因此是8。字符串
printf("%p\n", &s)
和 printf("%p\n", &t)
则有所不一样,&s
依然会返回 s
数组变量首位元素的指针地址,因此 &s == s
。而 &t
虽然存放了至关于 &s
的指针地址可是别忘了计算机是会为指针变量 t
也分配存储空间的,因此 t
有它本身的指针地址,结果固然 &t != t
。编译器
别觉得就这样GG了,它们之间还有一个很重要的区别。it
数组变量不能指向其余地方,建立指针变量的时候计算机会为它分配存储空间。那数组变量呢?io
实际上计算机只会为数组分配存储空间,但不会为数组变量分配任何存储空间,编译器会在数组变量出现的地方将它替换成数组的起始地址。编译
Over.变量