C++基础之数组

来源:互联网 发布:strcontains php 编辑:程序博客网 时间:2024/06/01 19:25

一、易错易忽略点注意:

1、数组必须在创建时将其大小确定下来,不能在以后改变大小。

int a[’a’] 正确,会自动把a转换为ASCII的97int n=100; int a[n];//错误   const int n=100;   int a[n];   //正确编译每次碰到一个变量名就对应一个空间访问的操作。而此时的n只有在运行时才能读取其值,进而确定其空间大小,所以编译报错。但是用堆内存可以(堆区数组)数组下标越界:编译时不会查出,运行时报错

2、全局数组(在函数外定义的数组)和静态数组(加上static修饰的数组定义)其元素总是被初始化为0。局部数组(在函数内部定义的数组)它们的值是不确定的。

3、数组的存储类型可以是auto、static、extern,但不能是regist的。

4、数组名是一个标识符,代表数组元素在内存中的起始地址-->(常量指针)。在函数调用时,实参数组名a代表一个固定的地址,或者说是指针型常量,因此要改变a的值是不可能的。

5、[ ] 下标运算符,通过算地址取出其中的值。


二、1维数组的理解

一维数组 int a[5];

数组名是一个地址常量,其指向为数组中第一个元素的地址。

a++;  错误   因为a为常量(地址常量)a==&a[0];  正确a[n]==*(a+n) = *(a+sizeof(int)*n)a[1]==*(a+1) = *(a+sizeof(int)*1)int *q;q=a;q==&a[0];q++;   =>   q=q+1;  =>  q=q+sizeof(int)*1q--;

三、2维数组的理解

二维数组 int a[2][3]  数组名:地址常量

一个数组在内存中进行存储,除了存储数组中的内容外,还需要额外的一个内存单元用于存储数组的头指针。因此a[2][3]占7个存储单元。

a、a[0]&a[0]&a[0][0]*(a+0) 它们的值相同,但是它们中有些类型不同!

                                             

int (*p) [3];  //() 和 [] 的优先级别相同,结合性为左结合,即从左往右看,变量p是一个指针,指向的是数组,因此 p为数组指针,p指向的是int [3]类型的数组。

解释上表:

。#1、 a : 相当于数组指针类型(数组指针是指向数组地址的指针,其本质为指针),指向的是一个数组地址。相当于一个二级指针常量。 

如上表所示,a是指针,该指针指向的是一个包含三个元素的一维数组的的首地址!!! 这 里可以将a[0]直接看做是数组名字,a[0][1]是这个一维数组的第二个元素。

a是直接指向a[0]的,a的(内容)值为指针-->即a[0]的地址(数组首地址)。

 

#2、 *(a+0) :(a本质是一个地址常量,这里相当于指针(类似p))a这个“指针”指向的是一个包含三个整型元素的数组的地址,*是取值运算符,取a这个地址处的内容,那便是a[0]。

a+0这个“指针”的值是第一个(行)包含三个整型元素的数组的地址

a+1这个“指针”的值是第二个(行)包含三个整型元素的数组的地址【之所以可以这样表示二维数组的第二行,是因为数组在内存中是线性存放的】

 

#3、a[0] :[ ]是下标运算符,通过算地址取出其中的值。

a是一个“指针”,指针所指向的值为一个数组(数组的首地址)[也就是说指针指向的是地址]。(指向指针的指针,这也是a是二级地址的由来)

a[0]就相当于通过算a所指向的地址,取出这个地址处的内容。我们将a[0]看做一个数组名后,那么a[0]这个数组名自然就相当于是一个一级指针。

 

#4、&a[0] : &为取地址运算符,对a[0]取地址,a[0]的地址为??我们知道a处的(内容)值为a[0]的地址。因此,a[0]的地址就为a。


a==&a[0]a[0]==*(a+0)==&a[0][0]int *q; //整型数组q=a[0]=&a[0][0];  //可以将a[0]和&a[0][0]的值赋给q。

a[1][1]=(*(a+1))[1]=*(*(a+1)+1 )a[1]==>*(a+1*sizeof(a[1]))sizeof(a[1])==sizeof(a[0])==4*3=12sizeof(a)=4*6=24指针加一:指针当前地址 + sizeof(指针数据类型)