指针

1.对形式参量使用 const

  函数之所以可以改变数组的内容,是因为函数使用了指针,从而能够直接使用原始数据。

  然而也许其他的函数并不希望修改数据。例如下面这个函数的功能是计算数组中所有元素的和,所以它不应该改变数组的内容。由于 ar 实际上是一个指针所以编程上的错误可以导致原始数据遭到破坏。

/*****错误的代码******/
int sum (int ar[], int n)
{
    int i;
    int total = 0;

    for (i =0; i < n; i++)
        total += ar[i]++;    //错误的增加了每个元素的值
    return total;
}

  为了避免此类错误,如果涉及意图是函数不改变数组的内容,那么可以在函数原型和定义的形式参量声明中使用关键字 const 。 例如 sum() 的原型和定义如下所示:

int sum (const int ar[], int n);    /* 原型 */

int sum (int ar[], int n)
{
    int i;
    int total = 0;

    for (i =0; i < n; i++)
        total += ar[i];    
    return total;
}

  这样使用 const 并不要求原始数据是固定不变的;这只是说明函数在处理数组时,应把数组当做是固定不变的。

  如果函数想修改数组,那么在生命参量时就不要使用 const ;如果函数不需要修改数组,那么在声明数组参量时最好使用const 。

2.指针与多维数组

2.1 指针与多维数组

  zippo[m][n] == *(*(zippo + m) + n)

 1 #include <stdio.h>
 2 int main(void)
 3 {
 4     int zippo[4][2] = { {2,4}, {6,8}, {1,3}, {5, 7} };
 5     
 6     printf("   zippo = %p,    zippo + 1 = %p\n",
 7                zippo,         zippo + 1);
 8     printf("zippo[0] = %p, zippo[0] + 1 = %p\n", 
 9             zippo[0],      zippo[0] + 1);
10     printf("  *zippo = %p,   *zippo + 1 = %p\n", 
11               *zippo,        *zippo + 1);
12     printf("zippo[0][0] = %d\n", zippo[0][0]);
13     printf("  *zippo[0] = %d\n", *zippo[0]);
14     printf("    **zippo = %d\n", **zippo);
15     printf("      zippo[2][1] = %d\n", zippo[2][1]);
16     printf("*(*(zippo+2) + 1) = %d\n", *(*(zippo+2) + 1));
17 
18     return 0;
19 }

在Vc++6.0中的输出结果为:

  输出显示出二维数组 zippo 的地址和一维数组 zippo[0] 的地址是相同的,均为相应的数组首元素的地址。然而,差别也是有的。在VC6.0里面,int 是4个字节长, zippo[0] 指向4字节长的数据对象,对 zippo[0] 加 1 导致它的值增加4 。数组名 zippo 是包含两个 int 数的数组的地址,因此它指向 8 字节长的数据对象,对 zippo 加 1 导致它的值增加8 。

  分析 *(*(zippo+2) + 1)

zippo第1个大小为 2 个 int 的元素的地址
zippo+2第3个大小为 2 个 Int 的元素的地址
*(zippo+2)第3个元素,即包含2个 int 值的数组,因此也是其第1个元素(int 值)的地址
*(zippo+2)+1包含2个 int 值的数组的第2个元素(int 值)的地址
*(*(zippo+2)+1)数组第3行第2个 int 的值(zippo[2][1])

2.2 指向多维数组的指针

  int (* pz) [2]; //pz 指向一个包含2个int值的数组

  该语句表明 pz 是指向包含2个 int 值的数组的指针。使用圆括号的原因是因为表达式中 [] 的优先级高于 * 。

  如果我们这样声明:  int * pax[2];                                                                

  那么首先 [] 与 pax 结合,表示 pax 是包含两个某种元素的数组。然后和 * 结合,表示 pax 是两个指针组成的数组。最后,用 int 来定义,表示 pax 是由两个指向 int 值的指针构成的数组。这种声明会创建两个指向单个 int 值的指针。

 1 #include <stdio.h>
 2 int main(void)
 3 {
 4     int zippo[4][2] = { {2,4}, {6,8}, {1,3}, {5, 7} };
 5     int (*pz)[2];
 6     pz = zippo;
 7     
 8     printf("   pz = %p,    pz + 1 = %p\n",
 9                pz,         pz + 1);
10     printf("pz[0] = %p, pz[0] + 1 = %p\n", 
11             pz[0],      pz[0] + 1);
12     printf("  *pz = %p,   *pz + 1 = %p\n", 
13               *pz,        *pz + 1);
14     printf("pz[0][0] = %d\n", pz[0][0]);
15     printf("  *pz[0] = %d\n", *pz[0]);
16     printf("    **pz = %d\n", **pz);
17     printf("      pz[2][1] = %d\n", pz[2][1]);
18     printf("*(*(pz+2) + 1) = %d\n", *(*(pz+2) + 1));
19     
20     return 0;
21 }

在Vc++6.0中的输出结果为:

2.3指针赋值事项

  把 const 指针赋给非 const 指针是错误的,因为可能会使用新指针来改变 const 数据。

  但是把 const 指针赋给 const 指针是允许的,这样赋值有一个前提:只进行一层间接运算。

int * p1;
const int * p2;
const int ** p3;

p1 = p2;    //非法,把const指针赋给非const指针
p2 = p1;    //合法,把非const指针赋给const指针
p3 = &p1;    //非法,把非const指针赋给const指针,进行多层间接运算

2.4函数和多维数组

  一般的,声明N维数组的指针时,除了最左边的方括号可以留空之外,其他都需要填写数值。

  int sum (int ar[][10][20][30], int rows);

  等效原型表示:  int sum(int (*ar)[10][20][30], int rows]);

  此处 ar 指向一个 10*20*30 的 int 数组。

 

 

转载于:https://www.cnblogs.com/wjtang/archive/2012/11/08/2755763.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值