数组和指针的区别

3 篇文章 0 订阅

发现好多人搞不清楚数组和指针的区别。

数组申明时编译器自动分配一片连续的内存空间

指针申明时只分配了用于容纳指针的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










  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值