C语言中指针变量和数组变量的区别
首先看下以下代码,猜猜看会输出什么?
#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[]的第一个元素的指针地址。记住数组变量可以被当作指针使用,它指向数组在存储器中的起始地址。
既然这样有些小伙伴可能会惊呆了,那为什么 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了,它们之间还有一个很重要的区别。
数组变量不能指向其他地方,创建指针变量的时候计算机会为它分配存储空间。那数组变量呢?
实际上计算机只会为数组分配存储空间,但不会为数组变量分配任何存储空间,编译器会在数组变量出现的地方将它替换成数组的起始地址。
Over.