C语言学习(5)---指针

来源:互联网 发布:审计软件分类 编辑:程序博客网 时间:2024/05/23 16:51

一、指针是C语言的灵魂

  1. # include <stdio.h>  
  2.   
  3. int main(){  
  4.     int *p;  //p是变量名,int *表示p变量存放的是int类型变量的地址,p是一个指针变量  
  5.     int i = 3;  
  6.       
  7.     //p = i; 这样写是错误的  
  8.     //p = 4; 这样写是错误的  
  9.     p = &i;  //将i变量的地址给p变量  
  10. //p保存了i的地址,因此p指向i,修改p的值不影响i的值,修改i的值也不影响p的值  
  11.       
  12.     return 0;  
  13. }  
  1. # include <stdio.h>  
  2.   
  3. int main(){  
  4.     int *p; //不表示定义了一个名字叫做 *p的变量  
  5. //应该这样理解:p是变量名,p变量的数据类型是 int *类型  
  6. //int *类型实际就是存放int变量地址的类型  
  7.   
  8.     int i = 3;  
  9.       
  10.     p = &i;  
  11.       
  12.     printf("*P = %d\n", *p);  
  13.     printf("i = %d\n", i);  
  14.     return 0;  
  15. }  
注释:1.如果p是个指针变量,并且p存放了普通变量i的地址,则p指向了普通变量
      2.*P 完全等同于 普通变量i  (有i出现的地方都可以替换成*p)

指针和指针变量的区别:

1.指针就是地址,地址就是指针,地址就是内存单元的编号,所以指针就是内存单元的编号

2.指针变量存放地址的变量,也就是说指针变量是存放内存单元编号的变量

3.指针和指针变量是两个不同的概念,但是要注意通常我们叙述时会把指针变量简称为指针,实际它们的含义不一样

二、指针的重要性:

1.表示一些复杂的数据结构

2.快速的传递数据

3.使函数返回一个以上的值(函数只能返回一个值)

4.能直接访问硬件

5.能够方便的处理字符串

6.是理解面向对象语言中引用的基础

  1. # include <stdio.h>  
  2.   
  3. int f(int a, int b);  
  4. void g(int * p ,int * q);  
  5.   
  6. int main(void){  
  7.       
  8.     int a = 100;  
  9.     int b = 200;  
  10.       
  11. //  a = f(a, b);  
  12.     g(&a, &b);  
  13.     printf("a = %d, b = %d\n", a, b);  
  14.       
  15.     return 0;  
  16. }  
  17. //只能修改一个值  
  18. int f(int a, int b){  
  19.       
  20.     return 1;  
  21. }  
  22. //这样被调函数可以修改主调函数一个以上的值  
  23. void g(int * p ,int * q){  
  24.     *p = 1;  
  25.     *q = 2;  
  26. }  

三、指针的定义

1、地址:内存单元的编号,地址是从零开始的非负整数。
2、范围:
      控制总线
CPU <---->    数据总线  <----->  内存条
      地址总线
控制线控制数据传输的方向 
数据线是传输数据
地址线是确定是控制哪个内存单元

cup<----->  数据总线 <-----> 内存条
一根线控制两个 0和1
两根线控制四个
n根线控制2的n次方个单元(字节)(每个单元是8位)

32位机 2x10^32
1G=2X10^30B(字节)
2x10^32 ~= 2X10^30*4  所以内存最大4G

3、指针:指针就是地址,地址就是指针,指针变量就是存放内存单元编号的变量。

指针本质就是一个操作受限(不能运算,只是编号)的非负整数(地址)

四、指针的分类

1、基本类型的指针

常见错误1:

  1. # include <stdio.h>  
  2.   
  3. int main(void){  
  4.     int *p;  //p指向一个垃圾值的地址,也就是一个垃圾地址  
  5.     int i = 5;  
  6.       
  7.     *p = i;  // 就是将i的值给了一个不知道的地址,这样写不对  
  8.     printf("%d\n", *p);  
  9.       
  10.     return 0;  
  11. }  
常见错误2:

  1. # include <stdio.h>  
  2.   
  3. int main(void){  
  4.     int i = 5;  
  5.     int *p;  
  6.     int *q;  
  7.       
  8.     p = &i  
  9.     //*q = p;  语法编译出错  
  10.     //*q = *p;  error  q指向一个垃圾地址  
  11.     q = p;  // error 可以读 q里面的垃圾地址,但是不能读*q的值,没有控制权限。  
  12.     printf("%d\n", *q);  
  13.       
  14.     return 0;  
  15. }  
一个经典的指针程序:
  1. # include <stdio.h>  
  2.   
  3. void huhuan(int i, int j);  
  4. void zhizhenhuhuan(int * a, int * b);  
  5. void huhuan3(int * a, int * b);  
  6.   
  7. int main(void){  
  8.     int a = 3;  
  9.     int b = 5;  
  10.       
  11. //  huhuan(a, b);  
  12. //  zhizhenhuhuan(&a, &b);  
  13.     huhuan3(&a, &b);  
  14.   
  15.     printf("a = %d,b = %d\n", a, b);  
  16.       
  17.       
  18.     return 0;  
  19. }  
  20.   
  21. void huhuan(int a, int b){  //不能完成互换,a,b是形参,单独分配内存  
  22.     int t;  
  23.       
  24.     t = a;  
  25.     a = b;  
  26.     b = t;  
  27. }  
  28.   
  29. void zhizhenhuhuan(int * a, int * b){ //不能完成互换,互换了指针的指向  
  30.     int * t;  
  31.   
  32.     t = a;  
  33.     a = b;  
  34.     b = t;  
  35. }  
  36.   
  37. void huhuan3(int * a, int * b){  //可以完成互换,传递的是地址,交换的是地址指向的值  
  38.     int t;  
  39.   
  40.     t = *a;  
  41.     *a = *b;  
  42.     *b = t;  
  43. }  
*的含义:

♥乘法   c = a*b;

♥定义指针变量 int * p;

♥取值运算符 *p

2、指针和数组的关系

一维数组名是个指针常量,它存放的是数组第一个元素地址

  1. int a[5];  
  2. int b[5];  
  3. //a = b 是错误的  a,b都是常量  
  1. # include <stdio.h>  
  2.   
  3. int main(void){  
  4.     int a[5];  
  5.       
  6.     printf("%#x\n", &a[0]);  
  7.     printf("%#x\n", a);  
  8.   
  9.     return 0;  
  10. }  
输出结果:0x12ff6c

0x12ff6c

如果p是个指针变量,则p[i]永远等价于 *(p+i)

确定一个一维数组需要两个参数:

数组第一个元素的地址

数组的长度

  1. //f函数可以输出任何一个一维数组的内容  
  2. # include <stdio.h>  
  3.   
  4. void f(int * pArr, int len){  
  5.     int i;  
  6.     for (i=0; i<len; i++)  
  7.         printf("%d  ", *(pArr+i));  
  8.     printf("\n");  
  9. }  
  10. int main(void){  
  11.     int a[5] = {1, 2, 3, 4, 5};  
  12.     int b[6] = {-1, -2, -3, 4, 5, -6};  
  13.     int c[100] = {1, 99, 22, 33};  
  14.       
  15.     f(a, 5); //确定一个数组:数组首地址和长度  
  16.     f(b, 6);  
  17.     f(c, 100);  
  18.       
  19.     return 0;  
  20. }  
  1. # include <stdio.h>  
  2.   
  3. void f(int * pArr, int len){  
  4.     pArr[3] = 88;  //pArr[3]等价于a[3]也等价于*(a+3)和*(pArr+3)   
  5.                    // *a==a[0]  
  6. }  
  7.   
  8. int main(void){  
  9.     int a[6] = {1, 2, 3, 4, 5, 6};  
  10.       
  11.     printf("%d\n", a[3]);  
  12.     f(a, 6);  // a和pArr都指向数组的第一个元素  
  13.     printf("%d\n", *(a+3));  
  14.       
  15.     return 0;  
  16. }  

五、指针变量的运算

指针变量不能相加,不能相乘,也不能相除(这些运算没有意义)

如果两个指针变量指向的是同一块连续空间中得不同的存储单元,则这两个指针才可以相减(这样减才有意义)

  1. # include <stdio.h>  
  2.   
  3. int main(void){  
  4.     int i = 5;  
  5.     int j = 10;  
  6.     int * p = &i;  
  7.     int * q = &j;  
  8.     //此时p和q不能相减  
  9.     int a[5];  
  10.     p = &a[2];  
  11.     q = &a[4];  
  12.   
  13.     printf("相减的结果为:%d\n", p-q);  
  14.     //此时p和q可以相减,相减的值指p和q单元相隔的个数  
  15.   
  16.     return 0;  
  17. }  
结果为:相减的结果为:-2

六、指针变量长度

预备知识:

sizeof(数据类型);或者 sizeof(变量名);返回该数据类型所占的字节数

例如: sizeof(int) = 4 sizeof(char) = 1

  1. # include <stdio.h>  
  2.   
  3. int main(void){  
  4.     char ch = 'A';  
  5.     int i = 90;  
  6.     double x = 66.6;  
  7.     char * p = &ch;  
  8.     int *q = &i;  
  9.     double *r = &x;  
  10.       
  11.     printf("%d  %d  %d\n"sizeof(p), sizeof(q), sizeof(r));  
  12. }  
输出的结果:4  4  4

七、多级指针

  1. # include <stdio.h>  
  2.   
  3. int main(void){  
  4.     int i = 10;  
  5.     int * p = &i;  
  6.     int ** q = &p;  
  7.     int *** r = &q;  
  8.       
  9.     printf("i = %d\n", ***r);  
  10.   
  11.     return 0;  
  12. }  
结果: i = 10
0 0
原创粉丝点击