StarkerSong Get Busy Living

数组和指针详解

2016-09-11

今天晚上腾讯在线笔试,总结下整体难度不大,都是偏于基础的,但是对于选择题中遇到的多级指针以及操作系统中的时间片轮转调度两个选择题都没有复习到位,大题目的两个编程题都非常简单,可惜以为最后一题很难,把过多的经历放在数据库设计和扔玻璃球上了。在昨天看了女神的在线笔试的笔记,差点跪求收下我的膝盖,所以今天笔试的时候特地准备好纸笔记下了两个没掌握好的知识点,针对这两个知识点做个详细的记录和分析。

数组和指针

一维数组与数组指针

char a[3];

数组名代表首元素的首地址,相当于&a[0],但是a[0]类型为char,所以&a[0]类型为char *,所以有下面等价表达式:

char *p=a;
char *p=&a[0];

对数组名取地址,类型为整个数组

char (*p)[3] = &a;

对类似于a+1,&a+1,&a[0]+1,sizeof(a),sizeof(&a),其实只要搞清楚指针的类型就可以迎刃而解。比如在面对a+1&a+1的区别时,由于a表示数组首元素首地址,其类型为char *,因此a+1相当于数组首地址值+sizeof(char);而&a的类型为char (*)[3],代表整个数组,因此&a+1相当于数组首地址值+sizeof(a)(sizeof(a)代表整个数组大小,但是无论数组大小如何,sizeof(&a)永远等于一个指针变量占用空间的大小,具体与系统平台有关)

二维数组与数组指针

char a[3][2];

可以将a[3][2]看成是一个具有3个元素的一维数组,只是这三个元素分别又是一个一维数组。

  1. 第一维:将a[3][2]看成三个元素的一维数组,元素为a[0],a[1],a[2],其中,a[0],a[1],a[2]又分别是一个具有两个元素的一维数组(元素类型为char)。
  2. 第二维:将a[0],a[1],a[2]看成代表第二维数组的数组名。
char (*p)[2]  = a;//a为第一维数组的数组名,类型为char (*)[2]
char * p = a[0];//a[0]维第二维数组的数组名,类型为char *

对a取地址操作代表整个数组的首地址

char (*p)[3][2] = &a;

三维数组与数组指针

char a[3][2][2];

其实三维数组和上述二维数组的思路是相同的,只要把它看做是一维数组里面存储的是数组类型的元素就可以。

char (*p)[3][2][2] = &a;//对数组名取地址类型为整个数组
char (*p)[2][2]  = a;
char (*p) [2]  = a[0];//或者a[1]、a[2]
char *p = a[0][0];//或者a[0][1]、a[1][0]...

多级指针

其实指针这个问题我已经看过几遍了,但是每次都看明白了,下次遇到还是感觉雾里看花,归咎到底还是没有深刻理解。在解读多级指针之前,首先得要搞清楚以下基础知识:

  • 实际上并不存在多维数组,所谓的多维数组本质上是用一维数组模拟的。

  • 数组名是一个常量(意味着不允许对其进行赋值操作),其代表数组首元素的首地址。

  • 数组与指针的关系是因为数组下标操作符[],比如,int a[3][2]相当于*(*(a+3)+2)

  • 指针是一种变量,也具有类型,其占用内存空间大小和系统有关,一般32位系统下,sizeof(指针变量)=4。

  • 指针可以进行加减算术运算,加减的基本单位是sizeof(指针所指向的数据类型)。

  • 对数组的数组名进行取地址&操作,其类型为整个数组类型。

  • 对数组的数组名进行sizeof运算符操作,其值为整个数组的大小(以字节为单位)。

  • 数组作为函数形参时会退化为指针。

对于以上部分都是基础部分,在编码中也常会遇到这些知识点,但是如果要让我在面试中脱口而出一一罗列以上数组和指针特点,估计我要挂壁了


char *p = "my name is xingxu.";
char **pp = &p;//二级指针
char ***ppp = &pp;//三级指针

当数组作为形参时,参数会退化为指针,例如我们常用来传递命令参数的主函数形如下面是等价的。

int main(int argc,char ** argv)
int mian(int argc,char* argv[]) 

如果要获取分配的内存,可以通过下面两种方法:

  • 函数返回值
    void * get_memery(int size)
    {
       void *p = malloc(size);
       return p;
     }
  • 二级指针
    int get_memery(int** buf,int size)
    { 
      *buf = (int *)malloc(size);
      if(*buf == NULL)
          return -1;
      else
          return 0;
    }
     int *p = NULL;
     get_memery(&p,10);

Comments