zoukankan      html  css  js  c++  java
  • 2015.8.5关于指针的个人理解

    1、要区分指针的类型指针所指向的类型

    1.1指针的类型:把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。

    eg:   int *a;去掉‘a’,得到“int *”,所以该指针的类型就是int *,即该指针是一个指向整型变量的指针;

           char *str;去掉“str”,得到"char *",所以该指针的类型就是char *,即该指针是一个指向char型变量的指针;

           int **ptr;去掉“ptr”,得到“int **”,故改指针的类型就是“int **,即该指针是一个指向整型指针变量的指针”

           int (*ptr)[3];去掉“ptr”,得到“int(*)[3]”,故改指针的类型就是int(*)[3],即该指针是一个指向整型数组的指针。

    1.2指针所指向的类型:把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。

    eg:int *a;去掉‘a’和‘*’,得到“int”,故该指针所指向的类型是int型;

          char *str;去掉“str”和‘*’,得到“char”,故该指正指向的类型是char型;

          int **ptr;去掉“ptr”和‘*’,得到“int *”,故该指针指向的类型是int *型;

          int (*ptr)[3];去掉“ptr”和‘*’,得到int [3],故该指针指向的是int [3]型。

    2、要理解‘*’在不同场合的不同意义

    1 void main()
    2 {
    3 int *a;
    4 int b=10;
    5 
    6 a=&b;
    7 
    8 printf(”%d“,*a);
    9 }

    第3行int *a(定义的时候)‘*’只是表示此时定义的这个变量是指针变量

    第8行中的*a,其中的‘*’表示”指向“,”*a“表示指针变量a所指向的变量,也就是b

    3、不能给野指针瞎赋值

    eg:

    1 void swap(int *p1,int *p2)
    2 {
    3 int *temp;
    4 *temp=*p1;
    5 *p1=*p2;
    6 *p2=*temp;
    7 }

    第3行定义了一个指向整型变量的指针temp,接下来在第4行就给*temp赋值。这是错误的。

    因为*temp是指针temp所指向的变量,但是由于未给temp赋值,所以temp并没有确定的值,所以temp所指向的内存单元也就是不可预见的。那么对*temp赋值就是向一个未知的存储单元赋值,但是这个未知的存储单元有可能是一个存放着重要数据的单元,这样就会造成系统运行错误。

    4、数组名和指针变量的区别

    1 int i, *pa, a[] = {3,4,5,6,7,3,7,4,4,6}; 
    2 pa = a; 
    3 for (i = 0; i <= 9; i++) 
    4 { 
    5 printf("%d
    ", *pa); 
    6 pa++; /*注意这里,指针值被修改*/ 
    7 }

    如上述代码所示,在循环体中我们采用pa++来输出数组中所有元素,但是如果将循环体中的pa改成a还对吗?

    答案是不对,为什么呢?因为pa是一个指针变量,而数组名a实质上是一个指针常量,常量的值是不允许修改的,其指向的是数组的首地址。

    5、函数参数传递的三种不同方式

    5.1、值传递

    eg:

    void Exchg1(int x, int y) /* 定义中的x,y变量被称为Exchg1
    函数的形式参数*/ 
    { 
    int tmp; 
    tmp = x; 
    x = y; 
    y = tmp; 
    printf("x = %d, y = %d.
    ", x, y); 
    } 
    
    
    main() 
    { 
    int a = 4,b = 6; 
    Exchg1(a, b); /*a,b变量为Exchg1函数的实际参数。*/ 
    printf("a = %d, b = %d.
    ”, a, b); 
    return(0); 
    } 

    上述代码的运行结果是:

    x=6,y=4

    a=4,b=6

    函数Exchg1在被调用时只是把实参a,b的值传递给了形参x,y,而在函数Exchg1内对变量a,b本身没有进行别的任何操作,在该函数体内操作的只是变量x,y,故在变量a,b内存储的值还是没有发生改变。以上这种函数参数传递方式叫作值传递方式。

    5.2、地址传递方式

     1 void Exchg1(int *x, int *y) /* 定义中的x,y变量被称为Exchg1
     2 函数的形式参数*/ 
     3 { 
     4 int tmp; 
     5 tmp = *x; 
     6 *x = *y; 
     7 *y = tmp; 
     8 printf("*x = %d, *y = %d.
    ", *x, *y); 
     9 } 
    10 
    11 
    12 main() 
    13 { 
    14 int a = 4,b = 6; 
    15 Exchg1(&a, &b); /*a,b变量为Exchg1函数的实际参数。*/ 
    16 printf("a = %d, b = %d.
    ”, a, b); 
    17 return(0); 
    18 } 

    上述代码的运行结果是:

    *x=6,*y=4

    a=6,b=4

    函数Exchg1的入口参数是两个指向整型变量的指针,在该函数体内,这两个指针所指向的内存单元的值被交换。于是乎在主函数中调用该函数时,传递给该函数的是变量a,b在内存单元中的地址,而该函数执行的操作正是将这两个单元地址里面的值进行交换,故该函数运行结束之后a,b的值已经进行了交换。这种函数参数的传递方式叫作地址传递方式。

    5.3、引用传递方式

     1 void Exchg3(int &x, int &y) /* 注意定义处的形式参数的格式与
     2 值传递不同*/ 
     3 { 
     4 int tmp = x; 
     5 27
     6 x = y; 
     7 y = tmp; 
     8 printf("x = %d, y = %d.
    ", x, y); 
     9 } 
    10 main() 
    11 { 
    12 int a = 4; 
    13 int b = 6; 
    14 Exchg3(a, b); /*注意:这里调用方式与值传递一样*/ 
    15 printf("a = %d, b = %d.
    ”, a, b); 
    16 } 

    这种函数参数传递方式叫作引用传递方式,为什么叫作引用传递方式呢?因为在形参x、y前都有一个取地址符号“&”。有了这个,调用Exchg3时函数会将a、b 分别代替了x、y了,我们称:x、y分别引用了a、b变量。这样函数里头操作的其实就是实参a、b本身了,也就是说函数里是可以直接修改到a、b的值了。

     6、最后的一点补充:

    6.1:如果指针变量p已指向数组中的一个元素,则p+1指向的是同一数组中的下一个元素,p-1指向的是同一数组中的上一个元素。

    caution:执行p+1时并不是将p的值简单地加1,而是加上一个数组元素所占用的字节数

    6.2:在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长

  • 相关阅读:
    03.《架构漫谈》阅读笔记
    02.《架构漫谈》阅读笔记
    03.《架构之美》阅读笔记
    02.《架构之美》阅读笔记
    01.《架构之美》阅读笔记
    软件架构中的质量属性--以淘宝网为例(小论文)
    MVC框架介绍分析
    论面向服务架构设计及其应用
    1.26学习进度总结
    1.24学习进度总结
  • 原文地址:https://www.cnblogs.com/wan0807/p/4707420.html
Copyright © 2011-2022 走看看