指针与数组

在学习C语言中一定绕不开指针与数组,在使用时我们发现他们的用法是如此的相似,而又有所区别。这就使得我们的理解有所困难,为了更好地使用,我们必须清楚地理解它。

1.指针

什么是指针?
指针是一种数据类型,用他定义的变量保存的内容是地址。
可以简单认为:指针就是地址。
既然指针是一种数据类型,那么它就有对应的大小,像int为4字节,char为1字节。指针在32位平台下的大小是4字节,与前面的int,char无关。

int *p=NULL;

这里定义了一个指针,p是一个指针变量,它保存的是0X00000000这个地址(指向0X00000000),int代表的不过是p所指向的内存中保存的是int类型的数据。

2.数组

什么是数组?
数组就是一群相同类型元素的集合。

int a[10];

这里定义了一个整形数组,同样它也有大小,编译器会根据你的数组元素类型(这里是int)与个数(10)来确定要开辟的内存空间的大小(4*10=40字节)。
a指的是这个数组的名字,a[0]指的是数组的第一个元素。

3.访问形式

1.指针形式访问

char *p="hello";
char arr[]="world";

要取得’e’字符和’r’字符,可以这做:

*(p+1);
*(arr+2);

p+1代表着首先获得p指向的字符串的首地址(指向h),再加上1的偏移量(指向e)随后进行解引用,的到e字符。
arr+2也是同理。

2.下标形式访问
还是上面的例子,要取e,可以用p[1],要取r,可以用arr[2]。

p[1];
arr[2];

这所代表的也是先取首地址再加上偏移量再取值。

由这我们可以看到,指针形式与下标形式的访问原理都是一样的,只是写法不同而已。

4.地址

1.数组的地址
数组的地址指的是代表整个数组的地址,那数组名在什么情况下才指的是整个数组的呢?答案是只有一种,那就是在使用关键字sizeof的时候:

int a[]={1,2,3,4,5};
sizeof(a);	//这时a指的是整个数组

除了这种情况,在其他时候a单独出现时指的都是数组首元素的地址。
那怎样才能再取得整个数组呢?
答案是&a

main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}

在这个例子中,*(a+1)是数组首元素+1再解引用,得到的值是2。
而ptr=(&a+1)指的是让ptr指向下一个数组的首地址,在内存上看来就是指向元素5的下一个字节。此时再进行ptr-1,此时ptr指向的就是元素5,解引用后的到数字5。

5.多级指针和多维数组

1.多级指针

int *p=NULL;

定义一个指针(变量)指向NULL。此时我们知道p是一个指针变量,既然是变量,那它和int a;char b;这些变量一样都是在内存的栈上保存的,既然是在内存中保存那么它就有地址,此时若是再定义一个指针指向这个地址

int **q=p;

那么q就是二级指针,如此一来,三级指针不过就是再定义一个变量指向q,往后的多级指针也同理。
既然二级指针指向的是一级指针的地址那么对二级解引用自然得到的就是一级指针,再解引用得到的才是一级指针所指向的内容。多级指针也同理。
在这里插入图片描述
2.多维数组
数组是用来保存相同类型元素的集合,那么这些元素自然也可以是数组,那么,当一个数组里面的元素是一个个的数组时,它就变成了二维数组。而三维数组也就是在那个作为数组元素的数组中再保存一个数组,其余的多维也就同理。

a{a1{...},a2{...},a3{...},a4{...}}		//二维数组

6.传参

1.指针传参

void GetMem(char * p, int num)
{
p = (char *)malloc(num*sizeof(char));
}
int main()
{
char *str = NULL;
GetMem(str,10);
strcpy(str,”12345”);
free(str);		
return 0;
}

此例中free并没有起作用,得到malloc内存地址的是调用函数时函数自己创建的一个指针,但是当函数调用完毕,该指针就被释放了,所以无效。。
所以得到结论,指针传参时只是把指针变量拷贝了一份传给了函数,自己本身并没有传递。

2.数组传参
之前说到,除了在sizeof()中使用,当数组名单独出现时代表的都是数组首元素的地址。于是,在用数组名传参时,传递的其实是数组首元素的地址,也就是一个指向首元素的指针。
所以传参时可以这样写:

fun(a[]);		fun(a);		fun(a[][2]);

又上我们看到数组传参时候第一维可以省略,而后面的维度是不能省略的。我们可以这样理解这条规则:
一个二维数组a[3][3],它的元素是三个一维数组,而一位数组在作为一个元素时,它内部有多少元素就成为了我们必须知道的,于是他的元素个数也就成为了他的属性,必须写出来。

7.XXX指针,XXX数组

数组可以放元素,自然也就能放指针,这时就叫指针构成的数组,简称指针数组
同样,指针能指向任何变量,指向数组时就叫做数组的指针,简称数组指针。指向函数的指针就叫做了函数指针。
于是,指向指针数组的指针就叫指针数组指针,保存数组指针的数组就叫数组指针数组。这样可以一直玩下去,其实不过就是文字游戏罢了,只要我们理解了他的意思就不会混淆。

至此,我想问最后一个问题:指针和数组是什么关系?
答案是没关系。
他们之间有一些相似,比如都可以用下标和指针的形式来访问。
但他们是完全不同的,指针就是指针,数组就是数组,各位以后千万别混淆了。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值