指针的运算

Posted yangchang1117

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针的运算相关的知识,希望对你有一定的参考价值。

   其实,在C语言中,指针功能的强大,主要体现在指针变量的间接运算上,指针涉及的运算并不多。

    1、基本运算

    指针变量的基本运算包括赋值、取地址以及取值(间接运算)等运算。

    举例,如清单1: 

[cpp] view plain copy
 
  1. #include <stdio.h>  
  2.   
  3. int main(void)  
  4. {  
  5.     int a = 5;  
  6.     int *p = &a;  
  7.   
  8.     int b = *p;  
  9.     *p = 9;  
  10.   
  11.     printf("p = %p, &a = %p, &p = %p\n", p, &a, &p);  
  12.     printf("a = %d, b = %d\n", a, b);  
  13.   
  14.     return 0;  
  15. }  

    例子输出结果: 

[cpp] view plain copy
 
  1. p = 0xbfee8388, &a = 0xbfee8388, &p = 0xbfee8384  
  2. a = 9, b = 5  

    第6行的意思是把整型变量a的地址赋给指针变量p(这时可以说p指向了a),然后使用间接运算符(*),像第8和第9行那样,通过p来间接地使用a。

    第5行的语句再平常不过了,其实是有深意的,在大多数编程语言中用同一符号(如变量名a)来表示它的地址和地址中的内容(即值),编译器根据上下文环境来判断它的具体含义。如例子中的第8行的意思是把变量a的值(即整数5)赋给b(在这种情况下a被叫做右值),而第9行的意思是往a的地址(即0xbfee8388)中存储一个整数9(在这种情况下a被叫作左值),所以变量既可作为左值,也可作为右值。

    指针变量作为一种变量,当然既可以给它赋值(如例子中把变量a的地址赋给指针变量p),也可以通过取址运算符(&)来取它的地址(如第11行打印出指针变量p的地址值0xbfee8384)。

    取值运算的复杂用法,如清单2: 

[cpp] view plain copy
 
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4.   
  5. void func(char **p, int num)  
  6. {  
  7.     *p = (char *)malloc(num);  
  8. }  
  9.   
  10. int main(void)  
  11. {  
  12.     char *str = NULL;  
  13.   
  14.     func(&str, 20);  
  15.   
  16.     strcpy(str, "hello world!");  
  17.   
  18.     printf("%s\n", str);  
  19.   
  20.     free(str);  
  21.   
  22.     return 0;  
  23. }  

    例子输出结果: 

[cpp] view plain copy
 
  1. hello world!  

    在例子中的第14行,通过函数调用把指针变量str的地址赋给二级指针变量p,然后在第7行通过*p来间接地使用str,这时str中的值为所分配的20个字节内存的首地址,接着往这段内存中拷贝字符串,最后打印字符串并释放这段内存。

    2、加减和求差

    指针变量加1的意义与整型变量加1的意义不同。

    举例,如清单3: 

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

    例子输出结果: 

[cpp] view plain copy
 
  1. address start = 0xbfeabab8, end = 0xbfeabad4  
  2. *(start+2) = 16, *(--end) = 12  
  3. (--end) - (start+2) = 3  

    首先使用指针变量start和end分别指向数组a的第一个元素和最后一个元素,然后从start+2(即0xbfeabac0,通过式子0xbfeabab8+2*sizeof(int)算出)的地址中取得整数16,和--end(即0xbfeabad0,通过式子0xbfeabad4-1*sizeof(int)算出)的地址中取得整数12,从中可知,指针变量加1是加一个数据类型(就是声明指针变量时所使用的数据类型)的大小。

    指针变量求差的意义不大,可以得到数组两个元素之间的距离,如例子中元素7和元素3相隔3个元素。

    3、比较

    指针变量的比较就是比较指针变量值的大小以及是否相等,与其他数据类型的比较类似。

    如清单4: 

[cpp] view plain copy
 
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. int main(void)  
  5. {  
  6.     char *p = (char *)malloc(10);  
  7.   
  8.     if (p == NULL)  
  9.     printf("failed to allocate memory.\n");  
  10.     else  
  11.     printf("allocate memory successfully.\n");  
  12.   
  13.     free(p);  
  14.   
  15.     return 0;  
  16. }  

    例子输出结果:

[cpp] view plain copy
 
  1. allocate memory successfully.  

    例子中,若malloc的返回不为NULL即表示内存分配成功。

以上是关于指针的运算的主要内容,如果未能解决你的问题,请参考以下文章

C语言指针Ⅶ 指针运算指针+-整数指针-指针指针的关系运算标准关系标准规定指针和数组二级指针指针数组。

共享指针 [] 运算符和 ++ 运算符

C 指针的算术运算

C 指针的算术运算

#运算符不同的指针类型数组和指针指针运算堆栈静态区只读区下标VS指针

C 语言结构体 ( 指针运算与指针内存操作 | 结构体成员偏移量计算 )