指针与数组

  指针是一种用于保存变量地址的变量,其本质是变量,只不过这种变量用于保存变量的地址。指针的特殊之处有两点:
  1、指针常常是表达某个计算的唯一途径;
  2、同其他方法相比,使用指针通常可以生成更高效、更紧凑的代码。 这两点会在后面说到。此外,还必须注意到,指针和数组之间的关系不是一般的密切。



指针与地址

  一元运算符”&”在这里作为取址运算符(此外,他还是按位与运算符),用于取一个对象的地址。
  

p = &c ;

  将把变量c的地址赋给变量p,我们称p为“指向”c的指针。需要注意的是,取址运算符&只能应用于内存中的对象,即变量和数组元素,不能作用于表达式、寄存器和常量。
  当*作用于指针变量时,将访问指针指向的对象。下面,我们假定x和y是整型变量,而ip是指向整形变量的指针:
  

int x = 1, y = 2, z[10];
int *ip;          /* ip is a pointer to int */
ip = &x;          /* ip now points to x */
y = *ip;          /* y is now 1 */
*ip = 0;          /* x is now 0 */
ip = &z[0];       /* ip now points to z[0]  */

  其中,

int *ip

  该声明语句表明表达式*ip 的结果是 int 类型。这里,声明指针时需指明其类型,是因为指针只能指向特定类型的对象(一个例外情况是指向 void 类型的指针可以存放指向任何类型的指针)。
  在 x 可以出现的任何上下文中都可以使用*ip,也就是说两者完全相等?那二者的差别在哪里呢?
  一元运算符*和&的优先级比算术运算符的优先级高
  指针之间也可以相互赋值:
  

iq = ip ;

  将把 ip 中的值拷贝到 iq 中, 这样,指针 iq 也将指向 ip 指向的对象。

指针与函数参数

  由于 C 语言是以传值的方式将参数值传递给被调用函数。 因此, 被调用函数不能直接修改主调函数中变最的值。例如, 排序函数可能会用一个名为 swap 的函数来交换两个次序颠倒的元素。 但是, 如果将swap 函数定义为下列形式:

void swap(int x, int y)  /* WRONG */
 {
     int temp;
     temp = x;
     x = y;
     y = temp;
 }

  则下列语句无法达到该目 的。
  

swap( a, b);

  这是因为,由于参数传递采用传值方式, 因此上述的 swap 函数不会影响到调用它的例程中的参数 a 和 b 的值。 该函数仅仅交换了 a 和 b 的副本的值。
  调用函数swap( a, b)时,仅仅是将a赋值给x,将b赋值给y,不会对a和b产生任何影响。
  那么, 如何实现我们的目标呢,可以使主调程序将指向所要交换的变量的指针传递给被调用函数, 即:

swap( &a, &b);

  由于一元运算符&用来取变量的地址, 这样&a 就是一个指向变量 a 的指针。 swap 函数的所有参数都声明为指针, 并且通过这些指针来间接访问它们指向的操作数。

void swap(int *px, int *py)  /* interchange *px and *py */
 {
     int temp;
     temp = *px;
     *px = *py;
     *py = temp;
 }

  指针参数使得被调用函数能够访问和修改主调函数中对象的值。



  我们来看这样一个例子:
  函数 getint 接受自由格式的输入, 并执行转换, 将输入的字符流分解成整数, 且每次调用得到一个整数。 getint 需要返回转换后得到的整数, 并且, 在到达输入结尾时要返回文件结束标记。 这些值必须通过不同的方式返回。 EOF(文件结束标记) 可以用任何值表示, 当然也可用一个输入的整数表示。
  下面的循环语句调用 getint 函数给一个整型数组赋值:

 int n, array[SIZE] ,  getint( int *);
 for (n = 0;  n < SIZE && getint( &array[n] )  != EOF;  n++)

  每次调用 getint 时,输入流中的下一个整数将被赋值给数组元素 array[n] , 同时, n 的值将增加 1。 请注意, 这里必须将 array[n] 的地址传递给函数 getint, 否则函数 getint将无法把转换得到的整数传回给调用者。
  该版本的 getint 函数在到达文件结尾时返回 EOF, 当下一个输入不是数字时返回 0, 当输入中包含一个有意义的数字时返回一个正值。

 #include <ctype.h>
 int getch(void) ;
 void ungetch(int);
 /* getint:  get next integer from input into *pn */
 int getint( int *pn)
 {
     int c, sign;
     while (isspace(c = getch( )))  /* skip white space */
    if (!isdigit( c) && c != EOF && c != ' +' && c ! = ' -') {
     ungetch(c);  /* it is not a number */
     return 0;
 }
 sign = (c == '-' )  ? -1 : 1;
 if (c == '+' || c == '-')
 c = getch() ;
 for (*pn = 0;  isdigit(c) ,  c = getch())
 *pn = 10 * *pn + (c - ' 0');
 *pn *= sign;
 if (c != EOF)
 ungetch(c);
 return c;
 }

  在 getint 函数中, *pn 始终作为一个普通的整型变量使用。其中还使用了 getch 和 ungetch两个函数, 借助这两个函数,函数 getint 必须读入的一个多余字符就可以重新写回到输入中。



指针与数组

  通过数组下标所能完成的任何操作都可以通过指针来实现。一般来说,用指针编写的程序比用数组下标编写的程序执行速度快, 但另一方面, 用指针实现的程序理解起来稍微困难一些。
  如果 pa 指向数组中的某个特定元素, 那么, 根据指针运算的定义, pa+1 将指向下一个元素, pa+i 将指向 pa 所指向数组元素之后的第 i 个元素, 而 pa-i 将指向 pa 所指向数组元素之前的第 i 个元素。 因此, 如果指针 pa 指向 a[0] , 那么(pa+1) 引用的是数组元素a[1] 的内容, pa+i 是数组元素 a[i] 的地址, (pa+i) 引用的是数组元素 a[i] 的内容。
  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值