静态数组与动态数组的区别以及二维数组地址详解
2014-04-16 11:08
676 查看
静态数组:
在编译期间在栈中分配好内存的数组,在运行期间不能改变存储空间,运行后由系统自动释放。int a[10]; char b[10]; float c[10]; test a[10]; //test为自定义的类,定义一个包含十个test对象的数组以上都是静态数组的声明方式。需要注意的是静态数组是在编译期间就已经分配好内存,所以一定要指定数组的大小,不能以变量作为数组的大小
如:
int i; char a[i]; //这是不允许的,编译期间不能确定i的值,所以无法明确数组的大小,导致编译失败
动态数组:
在程序运行后才分配内存的数组,需要人工手动去创建和释放。//C语言中利用malloc函数来创建动态数组 int i; scanf("%d",&i); char *p = (char *)malloc(sizeof(char)*i);//分配长度为i的字符数组空间,可以以下标的形式去访问数组。不需要时要调用free()函数手动释放。 //C++中,利用new关键字创建动态数组 int i ; cin>>i; char *p = new char[i];//分配长度为i的字符数组空间,可以以下标的形式去访问数组。不需要时要delete p,手动释放。
二维数组地址:
首先要了解(1)a[i] = *(a+i);
(2)a是数组的首地址也是第一个元素的地址。
(3)a+i代表的是第i个元素的地址。
(4)a+i并不是简简单单第一个元素的地址+i,而应该是第一个元素的地址+i*sizeof(数组类型)。
二维数组可以理解为是一个特殊的一维数组,它的每一个元素也都是一维数组。
二维数组a[3][2]可以理解为一个特殊的一维数组,其中每一个元素都是一个一维数组,如a[0][2]实际包含两个元素a[0][0]和a[0][1]。
如图可得到以下结论:
(1)a+i指向a[i][2]: a为数组a[3][2]的首地址,特殊的一维数组包含3个元素a[0][2],a[1][2],a[2][2]。由一维数组的性质“首地址+i”得到的是第i个元素的地址,所以a+i指向特殊一维数组的第i个元素。
(2)a[i]指向a[i][0]: 特殊的一维数组的每个元素又都是一个数组,如a[0][2]实际包含两个元素a[0][0]和a[0][1]。a[0]相当于一维数组名,指向首元素 a[0][0],所以a[i]指向a[i][0],a[i]+j指向a[i][j]。
从图中看似a+i和a[i]指向的都是a[i][0],其实不然。a+i指向的是a[i],因为a[i]=*(a+i),这个比较难理解的。
void main(){ int a[3][2]={1,2,3,4,5,6}; cout<<*a[1]<<endl; cout<<*(a+1)<<endl; }运行结果
a[i]的确指向的是a[i][0],但a+1取值后仍然是一个地址指向a[i][0]。
可以这样理解,a+i指向的是特殊一维数组的第i个元素,第i个元素还是一个一维数组。*(a+i)直面的意思是想取出第i个元素的内容,但a+i所指空间还是个数组,难道*(a+i)直接就能将整个数组取出来?要知道数组都是通过下标一个个进行访问的,不能整体获得。所以*(a+i)只是获得这个数组空间首元素的地址,这样就可以通过下标对内容进行访问。
最后总结一下:
对于二维数组a[3][2],若看成3行2列的形式。
(1)a+i指向第i行,此时还没有获得第i行元素首地址,没有办法访问其中的元素
(2)*(a+i)或a[i]指向第i行首元素,获得第i行元素的首地址。
(3)a[i]+j指向第i行第j个元素,可以通过a[i]第i行元素的首地址访问各个元素。关键是要记住a[i]=*(a+i),
a[i][j]=*([b]*(a+i)+j)。[/b]
[b]动态二维数组的创建:[/b]
[b]C++中:[/b]void main(){ int row,col; cin>>row>>col; //自定义行数和列数 int **a = new int*[row]; //分配指向行的指针数组,因为(*行指针)才能得到每行首元素的地址,所以可以理解为行指针是指向首元素指针的指针 for(int k=0; k<row; k++){ a[k] = new int[col]; //分配行指针所指向的数组 } for(k=0; k<row; k++){ delete [] a[k]; //释放所有行空间 } delete [] a; //释放行指针数组 }
C中:
void main(){ int row,col; scanf("%d,%d",&row,&col); //自定义行数和列数 int **a = (int**)malloc(sizeof(int *) * row); //分配指向行的指针数组 for(int k=0; k<row; k++){ a[k] = (int *)malloc(sizeof(int) *col); //分配行指针所指向的数组 } for(k=0; k<row; k++){ free(a[k]); //释放所有行空间 } free(a); //释放行指针数组 }
相关文章推荐
- 控制对对象的访问——代理模式详解(静态代理和动态代理的区别以及联系)
- C语言中二维数组名与数组地址、首行地址、首行首元素地址关系与区别详解(初学者必须掌握)
- 动态顺序表的代码实现以及与静态代码的区别
- 大端和小端格式的区别,以及二维数组和指针数组的学习总结。
- 【原】DelphiXe 中静态数组TByteArray和动态数组TBytes /array of byte 的区别
- 创建DLL文件 以及 动态加载和静态加载 以及两者之间的区别
- 动态网页与静态网页区别以及各自的优缺点
- C++中关于[]静态数组和new分配的动态数组的区别分析
- C/C++面试之算法系列--二维动态数组定义及二维静态数组与**P的区别
- DelphiXe 中静态数组TByteArray和动态数组TBytes /array of byte 的区别
- C++中关于[]静态数组和new分配的动态数组的区别分析
- 函数的返回值问题(返回指针和数组的区别)静态存储区、动态数据区、栈
- jsp中include指令静态导入和动态导入的区别详解
- 二维动态数组定义及二维静态数组与**P的区别
- C#超基础:静态数组与动态数组的区别
- 有关动态创建释放二维数组,以及指向数组的指针问题集合 .
- iOS库 .a与.framework区别以及Xcode 6制作动态及静态Framework
- 浅谈java中集合的由来,以及集合和数组的区别详解
- 使用BroadCast实现进程间通信以及静态注册和动态注册广播的区别
- 二维动态数组定义及二维静态数组与**P的区别