嵌入式学习资源——深入理解C语言指针的奥秘-2

接着我们的C语言指针的奥秘-1接着讲:

我们可以用一个指针和一个循环来遍历一个数组,看例子:

  例三:


intarray[20];
int*ptr=array;
...
//
此处略去为整型数组赋值的代码。
...
for(i=0;i<20;i++)
{
  (*ptr)++;
  ptr++

  这个例子将整型数组中各个单元的值加 1 。由于每次循环都将指针 ptr 1 ,所以每次循环都能访问数组的下一个单元。

  再看例子:

  例四:

   1 chara[20];

   2 int*ptr=a;

   ...
   ...

   3 ptr+=5;

  在这个例子中, ptr 被加上了 5 ,编译器是这样处理的:将指针 ptr 的值加上 5 sizeof(int) ,在 32 位程序中就是加上了 5 4=20 。由于地址的单位是字节,故现在的 ptr 所指向的地址比起加 5 后的 ptr 所指向的地址来说,向高地址方向移动了 20 个字节。在这个例子中,没加 5 前的 ptr 指向数组 a 的第 号单元开始的四个字节,加 5 后, ptr 已经指向了数组 a 的合法范围之外了。虽然这种情况在应用上会出问题,但在语法上却是可以的。这也体现出了指针的灵活性。

  如果上例中, ptr 是被减去 5 ,那么处理过程大同小异,只不过 ptr 的值是被减去 5 sizeof(int) ,新的 ptr 指向的地址将比原来的 ptr 所指向的地址向低地址方向移动了 20 个字节。

  总结一下,一个指针 ptrold 加上一个整数 n 后,结果是一个新的指针 ptrnew ptrnew 的类型和 ptrold 的类型相同, ptrnew 所指向的类型和 ptrold 所指向的类型也相同。 ptrnew 的值将比 ptrold 的值增加了 n sizeof(ptrold 所指向的类型 ) 个字节。就是说, ptrnew 所指向的 内存 区将比 ptrold 所指向的内存区向高地址方向移动了 n sizeof(ptrold 所指向的类型 ) 个字节。

  一个指针 ptrold 减去一个整数 n 后,结果是一个新的指针 ptrnew ptrnew 的类型和 ptrold 的类型相同, ptrnew 所指向的类型和 ptrold 所指向的类型也相同。 ptrnew 的值将比 ptrold 的值减少了 n sizeof(ptrold 所指向的类型 ) 个字节,就是说, ptrnew 所指向的内存区将比 ptrold 所指向的内存区向低地址方向移动了 n sizeof(ptrold 所指向的类型 ) 个字节

运算符 & *


  这里 & 是取地址运算符, * ... 书上叫做 " 间接运算符 "

   &a 的运算结果是一个指针,指针的类型是 a 的类型加个 * ,指针所指向的类型是 a 的类型,指针所指向的地址嘛,那就是 a 的地址。

   *p 的运算结果就五花八门了。总之 *p 的结果是 p 所指向的东西,这个东西有这些特点:它的类型是 p 指向的类型,它所占用的地址是 p 所指向的地址。

  例五:


inta=12;
intb;
int*p;
int**ptr;
p=&a;
//&a
的结果是一个指针,类型是 int* ,指向的类型是 int ,指向的地址是 a 的地址。
*p=24;
//*p
的结果,在这里它的类型是 int ,它所占用的地址是 p 所指向的地址,显然, *p 就是变量 a
ptr=&p;
//&p
的结果是个指针,该指针的类型是 p 的类型加个 * ,在这里是 int ** 。该指针所指向的类型是 p 的类型,这里是 int* 。该指针所指向的地址就是指针 p 自己的地址。
*ptr=&b;
//*ptr
是个指针, &b 的结果也是个指针,且这两个指针的类型和所指向的类型是一样的,所以用 &b 来给 *ptr 赋值就是毫无问题的了。
**ptr=34;
//*ptr
的结果是 ptr 所指向的东西,在这里是一个指针,对这个指针再做一次 * 运算,结果就是一个 int 类型的变量。  


  指针表达式

  一个表达式的最后结果如果是一个指针,那么这个表达式就叫指针表式。

  下面是一些指针表达式的例子:

  例六:


inta,b;
intarray[10];
int*pa;
pa=&a;//&a
是一个指针表达式。
int**ptr=&pa;//&pa
也是一个指针表达式。
*ptr=&b;//*ptr
&b 都是指针表达式。
pa=array;
pa++;//
这也是指针表达式。  


  例七:


char*arr[20];
char**parr=arr;//
如果把 arr 看作指针的话, arr 也是指针表达式

char*str;
str=*parr;//*parr
是指针表达式
str=*(parr+1);//*(parr+1)
是指针表达式
str=*(parr+2);//*(parr+2)
是指针表达式  


  由于指针表达式的结果是一个指针,所以指针表达式也具有指针所具有的四个要素:指针的类型,指针所指向的类型,指针指向的 内存 区,指针自身占据的内存。

  好了,当一个指针表达式的结果指针已经明确地具有了指针自身占据的内存的话,这个指针表达式就是一个左值,否则就不是一个左值。

  在例七中, &a 不是一个左值,因为它还没有占据明确的内存。 *ptr 是一个左值,因为 *ptr 这个指针已经占据了内存,其实 *ptr 就是指针 pa ,既然 pa 已经在内存中有了自己的位置,那么 *ptr 当然也有了自己的位置。

 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69914734/viewspace-2653637/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/69914734/viewspace-2653637/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值