数组与指针的混用

在C语言的声明里面,有时候在一个文件中声明了char *p;却在另外一个文件里面用extern char p[];来引用,或者在一个文件中声明了char arry[100];却在另外一个文件中用char *arry;来引用。这样乍看起来好像没事,实则是在挖坑,解析如下:(简化了在一个程序里面做实验)

  1. 定义为数组却声明为指针:

#include<stdio.h>

int main()
{
	char arry[10];
	strcpy( arry , "abcdef" );
	char **p;
	p = &arry;
	printf("&arry = %p p = %x\n",&arry,*p);
	//**p就是取地址0x64636261的值了,系统不允许
	
    return 0;
}

运行结果为:

&arry = 0022FF30 *p = 64636261

注意后面的那个*p的地址,恰好是abcd的asc码值。

2.定义为指针却声明为数组:

#include<stdio.h>

int main()
{
	char *p;	
	char arry[100];
	int i = 0;
	
	strcpy( arry , "abcdef" );	
	p = arry;
	
	printf("p = %p\n",p);
	for( i = 0 ; i < 7 ; i++ )
	{
		printf("p[%d] = %x\n",i,p[i]);
	}
	
    return 0;
}

运行结果为:

p = 0022FEC0
p[0] = 64636261
p[1] = 6665
p[2] = 0
p[3] = 763298da
p[4] = 2116ab91
p[5] = 0
p[6] = 0

注意p[0],p[1].,恰好是字符'abcdef'的asc值。

解释:

首先明白指针和数组的取值的不同,对于指针,取值分为三步,例如char *p="abc",p的地址是4624,p的值是5081(即p指向的地址,也就是abc保存的内存的首地址):

  1. 知道指针p的内容,也就是'4624'。

  2. 取p的值,即指向的内容,也就是'5081'。

  3. 取地址5081的内容,也就是abc。

对于数组,取值分为两步,例如char arry[10];strcpy( arry,"abcd" );

  1. 知道arry的地址,假设是4624.

  2. 取地址(4624+i)的值(或者说是取4624指向的地址存储的值),也就是abcd。

弄清上面的概念了,然后看第一种情况,定义为数组却声明为指针,一步步来,第一步都是知道变量的地址,第二步第二步应该取变量地址指向的地址存储的值,但是去变成了去变量地址指向的地址,也就是把存储的值当做地址了,然后再取这个地址指向的值。所以出现那种情况。

第二种情况,定义为指针却声明为数组,按照同样的道理,第一步都是取变量的地址,第二步应该去变量地址指向的值作为新的地址,却变成了取变量的地址的值,也就是把地址当做数组里面的数据来读取了,所以出现上面的情况。

你可能感兴趣的:(数组与指针的混用)