/*--------------------CSS部分-------------------*/ /*--------------------JS部分-------------------*/

指针和数组

数组的本质

上一章节讲过了指针,那么数组是什么,数据类型是什么,为什么数组做函数参数的时候会退化为指针,怎么理解。
先看一段代码:

int i,*p,a[] = {3,4,5,6,79};
p= a;
for (i=0;i<=9;i++)
{
    printf("%d\n",a[i])//通过数组名访问元素
    printf("%d\n",*a+i)//也可以这样
    printf("%d\n",p[i]//也可以这样
}

 

其实从程序上看数组和指针没有区别,数组从内存上是获取连续的内存区域进行数据存放,通过数组名获取了这块内存地址,所以数组名就是这块内存的代表,被定义为这块内存的首地址。数组名是一个地址,不可修改的常量,一个地址常量。数组名这个符号就是代表内存的首地址,本身就是这个地址。它是一个右值,不能放在=左边进行赋值,而指针是变量确实一个左值。
数组作为形参,在编译器当做指针来看,编译器从效率上将不提倡传入内存空间,但同时要操作一段内存空间,所以编译器默认的将数组名转化为指针,只是转化,传入的是数组地址而已。

多维数组和多级指针

在C语言中并不存在多维数组,从本质上讲是数组的数组,也就是数组的嵌套,各维之间有鲜明的层次关系。上一维把下一维看做作下一级数组,也就是数组的嵌套。
这里写图片描述
首先存储行号为0的n个元素,对于这n个元素按列号从小到大依次存储:紧接着存储行号为1的n个元素…最后存储行号为m-1的n个元素。
这里写图片描述
经过上面的分析,我们用sizeof来强化对数组的理解。

int a[5][8][9];
sizeof(a)//5*8*9*sizeof(int)
sizeof(a[0])//8*9*sizeof(int)
sizeof(a[1])//8*9*sizeof(int)
sizeof(a[0][3])//9*sizeof(int)
sizeof(a[2][2][4])//sizeof(int)
sizeof(&a[0])//sizeof(int)

 

从上面很容易得到a[0]是指向一个二维数组,通过a[0]可以获取这个二维数组内存值,当然用sizeof,就是获取一个二维数组的内存大小。&a[0]这是像获取指向二维数组指针的大小,也就是二维数组开始的内存地址。在数组中&a和&a[0],&a[0][0]是一样的,这就是都是内存开始的地址值。但是一定注意&a与&a[0]作为右值赋值是,是不一样的分别赋值给三级指针和二级指针

指针数组和数组指针

指针数组:array of pointers,即用于存储指针的数组,也就是数组元素都是指针

数组指针:a pointer to an array,即指向数组的指针

还要注意的是他们用法的区别,下面举例说明。

  1. int* a[4] 指针数组

    表示:数组a中的元素都为int型指针
    元素表示:a[i] (a[i])是一样的,因为[]优先级高于*

  2. int (*a)[4] 数组指针
    表示:指向数组a的指针
    元素表示:(*a)[i]
    其中()是不能去掉的,因为[]优先级比*高,这样就变成指针数组了
    注意:在实际应用中,对于指针数组,我们经常这样使用:

#include <iostream>

using namespace std;

int main()
{
int c[4]={1,2,3,4};
int *a[4]; //指针数组
int (*b)[4]; //数组指针
b=&c;//数组指针指向数组的地址,用数组的地址进行初始化
//将数组c中元素赋给数组a
for(int i=0;i<4;i++)
{
a[i]=&c[i];//指针数组,数组中存放的时指针,所以传入的内存地址
}
//输出看下结果,两者的输出方式不同
cout<<*a[1]<<endl; //输出2就对
cout<<(*b)[2]<<endl; //输出3就对
return 0;
}
View Code

 

重点讲解

数组和指针的区别
定义一个数组的时候,需要在栈中静态分配一块内存,那么需要知道内存的大小,因为定义数组的时候需要确定各维的上限。数组是一个可以拥有内存,保存变量的数组类型,数组名代表地址。指针是一个存储内存地址的数据类型,定义一个指针需要知道它指向对象的类型,不需知道对象的大小。
字符串常量
字符串常量在c语言就是一个字符数组,尽管外部表现和数组不一样,实际上字符串常量本身就是数组的首地址,并且具有数组类型。sizeof(“abdaaff”)是 7而不是4。重点区别是字符串常量放在静态存储区,不允许改变;数组在栈中静态分配
运算符&和*
&是取地址符,*是间接运算符。
&a的结果是一个指针,指针指向的类型就是a的类型加上。在运算中加上就是获取了指针指向的内存值。

版权声明:本文为博主原创文章,未经博主允许不得转载。

 

posted @ 2015-06-22 12:23  bldong  阅读(282)  评论(0编辑  收藏  举报