《C专家编程》读书笔记10

第十章  再论指针

 

10.1       多维数组的内存布局

 

        char pea[4][6]的内存布局。单个元素的存储和引用是以线性形式排列在内存中的。

        首先找到pea[i]的位置,然后根据偏移量[j]取得字符。因此,pea[i][j]将被编译器解析为:*( *(pea + i) + j)。

         

10.2       指针数组就是Iliffe向量

   

        可以通过声明一个一维指针数组,其中每个指针指向一个字符串来取得类似二维字符数组的效果。这样的声明如下:

        char *pea[4];

        用于实现多维数组的指针数组有多种名字,如“Iliffe”向量、“display”或者“dope”向量。

       

       

        这种数组必须用指向为字符串而分配的内存的指针进行初始化,可以在编译时用一个常量初始值,也可以在运行时用下面这样的代码进行初始化。

        for ( j = 0; j <= 4; j++) {  pea[j] = malloc(6);   }

        另一种方法是一次性地用malloc分配整个x×y个数据的数组,

        malloc( row_size * column*size * sizeof(char));

        然后,使用一个循环,用指针指向这块内存的各个区域。整个素组保证能够存储在连续的内存中,即按C用于分配静态数组的次序。它减少了malloc的维护性开销,但缺点是当处处理完一个字符串时无法单独将其释放。

 

        当看见squash[i][j]这样的形式时,并不知道它是怎样被声明的。有可能是以下几种

        int squash[23][12];    /*int类型的二维数组*/

        int *squash[23];      /*int类型指针的Iliffe向量*/

        int **squash;    /*int类型的指针的指针*/

        int (*squash)[12];    /*类型为int数组(长度为12)的指针*/

 

        数组的数组 与 字符串指针数组 的区别

         

       

10.3       在锯齿状数组上使用指针

 

        创建一个锯齿状数组

        char *turnip[UMPTEEN];

        char my_string[] = “your message here”;

        /*共享字符串*/

        turnip[i]= &my_string[0];

        /*拷贝字符串*/

        turnip[j] = malloc (strlen (my_string) + 1);

        strcpy(turnip[j], my_string);

        只要有可能,尽量不要选择拷贝整个字符串的方法。如果需要从两个不同的数据结构访问它,拷贝一个指针比拷贝整个数组快得多,空间也节省很多。另一个可能影响性能的因素是Iliffe向量可能会使字符串分配于内存中不同的页面中。

 

        “数组名被改写成一个指针参数”规则并不是递归定义的。数组的数组会被改写为“数组的指针”,而不是“指针的指针”。

         

       

        my_function_1( int fruit[2][3][5]) {;}

        my_function_2( int fruit[][3][5]) {;}

        my_function_3( int (*fruit)[3][5]) {;}

 

        int apricot[2][3][5];

        my_function_1(apricot);

        my_function_2(apricot);

        my_function_3(apricot);

 

        int (*p)[3][5]=apricot;

        my_function_1(p);

        my_function_2(p);

        my_function_3(p);

 

        int (*q)[2]][3][5] = &apricot;

        my_function_1(*q);

        my_function_2(*q);

        my_function_3(*q);

 

10.4       向参数传递一个一维数组

10.5       使用指针向函数传递一个多维数组

 

        能够采取的最好方法是放弃传递一个二维数组,把array[x][y]这样的形式改写为一个一维数组array[x+1],它的元素类型是指向array[y]的指针。在数组最后的那个元素array[x+1]里存储一个NULL指针,提示数组的结束。

 

        实参限制为除最左边一维外所有维都必须与形参匹配的数组。

        my_function ( int my_array[10][20]);

        它迫使函数只处理10行20列的int型数组。

        my_function ( int my_array[][20]);或者

        my_function ( int (*my_array)[20]);/* (*my_array)周围的括号是绝对必须的,这样可以确保它被翻译为一个指向(20个元素的int数组)的指针,而不是一个20个int指针的数组*/

        每行必须是20个整数的长度。

 

        Iliffe向量这种数据结构的美感在于:它允许任意的字符串指针数组,但必须是指针数组,而且必须是指向字符串的指针数组。这是因为字符串和指针都有一个显式的越界值(分别为NUL和NULL),可以作为结束标记。

 

10.6       使用指针从函数返回一个数组

 

        严格来说,无法直接从函数返回一个数组,但是,可以让函数返回一个指向任何数据结构的指针,当然也可以是一个指向数组的指针。

 

        int ( *paf())[20];

        paf是一个函数,它返回一个指向20个int元素的数组的指针。

 

10.7       使用指针创建和使用动态数组

 

        const int limit= 10;

        charplum[limit];/*错误,const int不能被当做一个整型常量表达式*/

         

 

         

10.8       轻松一下——程序检验的限制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值