发现好多人搞不清楚数组和指针的区别。
数组申明时编译器自动分配一片连续的内存空间
指针申明时只分配了用于容纳指针的4字节空间
作为函数参数时,数组参数和指针参数等价
数组名在多数情况下可视为常量指针,其值不能改变
指针的本质是变量,保存的值被看做内存中的地址。
名字上的区别:
数组名通常情况下被作为常量指针,只能作为左值出现,
对于数组
int a[5];
a和&的意义不同,a是数组元素的首地址,&a是整个数组的地址
看下面程序
#include <stdio.h>
int main()
{
int a[5] = {1,2,3,4,5};
int *p1 = (int *)(&a + 1);
int *p2 = (int *)(a + 1);
printf("p1[-1] = %d\n",p1[-1]); //5
printf("p2[-1] = %d\n",p2[-1]); //1
}
复制上的区别:
前面说了数组名一般只能作为左值出现,所以复值的时候只能一个一个来,而指针,则可直接进行
int a1[5] = {1,2,3,4,5};
int a2[5];
a2 = a1; //oOps
for(int i = 0;i < 5;i++)
{
a2[i] = a1[i]; //*a2++ == *a1++
}
char *p1 = "hello";
char *p2 = NULL;
p2 = p1; //正确,p2也指向了hello所在内存空间
计算内存空间大小的区别:
计算数组所占内存大小使用sizeof这个关键字,而计算字符串使用
size_t strlen(const char *s);函数,这里是好多人常出现错误的地方,不少人计算数组长度喜欢用strlen看下面例子
char s1[] = {'a','\0','c','c'};
int s2[] = {0,1,2,3,4,5,6,7,8};
printf("%d\n",strlen(s1));
printf("%d\n",strlen(s2));
上面两个均不能的到正确结果,究其原因还得探究
size_t strlen(const char *s)
;的实现。
size_t strlen(const char *str)
{
int len = 0;
assert(str != NULL);
while(*str != '\0')
{
len++;
}
return len;
}
看了原型大家都知道上面的结果是怎么来的了。再次强调求数组所占内存空间用sizeof关键字。
字符串数组和字符数组:
char s1[] = {'h','e','l','l','o'};
char s2[] = "hello";
printf("%d\n",sizeof(s1));
printf("%d\n",sizeof(s2)); //printf("%d\n",strlen(s2));结果是6
结果分别是4和5,在C中并没有字符串数据类型,只是用字符数组进行模拟,在最后以‘\0’结束;
字符串数组和字符串:
char s1[] = "hello";
char *s2 = "hello";
s1[1] = 'H';
s2[1] = 'H'; //oOps
这里主要是有个存储位置的问题。s2指向的一个字符串字面量,存在在只读代码段,其值不能被修改,s1是字符串数组存在栈空间。
作为形参传递:
数组名作为形参传递的时候是有退化的
void fun(int a[5]) <==> void fun(int a[]) <==> void fun(int *a)
所以在传递数组的时候还需要另一个参数,指示数组大小。其他情况
void fun(int *a[5]) <==> void fun(int *a[]) <==> void fun(int **a)
void fun(int a[5][6]) <==> void fun(int a[][6]) <==> void fun(int (*a)[6])
三维或更多维数组无法使用
定义数组使用为指针,定义为指针,使用为数组:
定义为数组使用为指针:
//b.c
#include <stdio.h>
char str[] = "hello";
//a.c
#include <stdio.h>
extern char *str;
int main()
{
printf("%s",str); //oOps,正解printf("%s",(char *)&str);
return 0;
}
定义为指针使用为数组
//b.c
#include <stdio.h>
char *str = "hello";
//a.c
#include <stdio.h>
extern char str[];
int main()
{
printf("%s",str);//输出什么?正解:printf("%s",(char *)(*(unsigned int *)str));
return 0;
}
这两个的形成原因是由于对数组和指针的处理方式不同(指针是间接的,数组是直接的)。
引用:http://blog.csdn.net/z1179675084/article/details/12951323