C++复合数据类型之数组和指针

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/z_dmsd/article/details/56842751

上一篇讲了C++的基本数据类型,这一篇就来讲一讲C++的复合类型:数组,指针和结构。

int a[10];

int* p;

注意:

1.a的类型不是数组,而是int数组,这强调了a数组是使用int类型创建的。

2.数组在内存中是按行优先存放的,即a[0],a[1]的地址是连续的,这在将来使用多维数组时需要注意

3.指针时一种特殊的类型,只有地址能够赋值给他。

创建了一个数组,就是在内存中分配一块连续的内存用于存放特定类型的数据,既然有内存,那么就会涉及到内存地址,这里的数组名a就是数组的地址,但需要注意的是数组有那么多个值,a是哪个值的地址呢?实际上a是数组第一个项的地址,即&a[0],但同时a也是整个数组的地址,即存放整个数组的内存块的地址可以通过&a获取这个地址。

前面说了,数组的内存是连续的,而这里又知道了数组第一个项的地址,那么就可以通过这个地址进行做加法获取数组其他项的地址了。涉及到地址的时候指针就可以派上用场了。数组名中存放的又是地址,也就是说其实数组名就是一个指针了。那就可以通过对数组首地址做加法获取其他地址,那就需要先了解一下指针算数了。

p+1加的并不是1,而是p的类型的字节数,这里p加的是4.

eg:假设p中存放的地址是1000,那么p+1就等于1004,

如果p的类型是double,且double长度为8个字节,那么p+1就是1008.

再回到之前的获取数组项地址,在使用a,而不是&a的时候a是数组第一项的地址,也就是说a的类型是数组项的类型,所以a+1就是地址加了4,正好是数组第二项的地址,即数组下标为n的地址可以通过a+n获取。那么&a+1是什么意思呢,既然&a是整个数组块的地址,也就是说&a的类型是这个数组类型,类型长度即数组长度了,即&a+1相当于加了数组的长度,这里是40,指向的是数组最后一项向后移动4个字节的位置。

所以数组项可以通过a[n]获取,也可以通过*(a+n)获取,若p=a,甚至可以通过p[n],*(p+n)获取

 

到这里,就已经明白了数组名就相当于一个指针了,那么接下来就讨论在函数间传递数组作为参数了。

之前没有使用数组传参的人可能会以为这个可以:

函数原型:void fun(inta[]);

函数调用: fun(a[10]);

这不是把整个参数传递了吗?实际上a[10]本身就是错的,数组越界了,即便没有越界,a[10]代表的也是数组的第10项而不是整个数组。那么如何传递数组呢?前面说过数组可以通过数组名来获取数组所有项的地址,有了地址自然就可以获取值了,所以,数组传参传递的实际是数组地址,也就是数组名了。

正确的调用方式是:

func(a);

因为传递的只是地址,所以函数内其实并不知道数组的长度,所以一般将数组的长度一起传入:

void fun(int a[],int length)

fun(a,10);

注意:1.C++并不会检查数组索引是否越界,即在函数中的a[10]也是合法的,但是其中的值是未知的。

既然传的是地址,那么函数的声明就可以改为如下:

void fun(int* a,int length);

这样也是正确的,在函数内部使用该数组的方式也是一样的。

注意: 1.在函数内部sizeof(a)=4,在数组声明处sizeof(a)=40,因为函数内部的a只是一个地址编译器并不会为他分配数组块大小的内存,而只是为他分配存放int型指针的内存,在数组声明处则不同,编译器会分配数组块大小的内存,并将这个地址保存到a(实际上就是分配的内存处)。


猜你喜欢

转载自blog.csdn.net/z_dmsd/article/details/56842751