zoukankan      html  css  js  c++  java
  • C指针思考-(1)

    首先记录下时间吧,@2016-08-18 23:26:22,这段时间看了同事的3本经典的书,《c缺陷和陷阱》,《c和指针》和《c专家编程》,感觉指针说的最多,多多少少还是有点领悟,记录下自己对指针的心得吧。

    1.很多时候多说指针和数组是等效的。这句话是有条件的,由于最近在看c++方面的资料(c现在工作不好找啊),有了新的理解。

       简单的来说,指针是一个间接寻址,而数组是直接寻址,在内存中,指针需要去一次地址后才能取到数据,而数组在内存中就是地址,直接根据地址就可以取到数据。所以在作为参数传递到函数中时,带入指针和带入数组,这个是等价的,因为传入的都是地址。这里我仔细想了想,某种意义上,指针也是传值操作,只不过类型是一个TYPE *而已,传入的是指向的那个地址(p的内容,也就是p的指向,也就是数据的地址,这里指针可以有很多理解,每段时间的理解都不一样,反正就是一个变量,存的是一个数据块的地址,指针根据这个地址去取数据)。

    2.看高质量的c及c++编程指南--指针参数是如何传递内存的,这个好纠结,真的好纠结,我看完了,还是不敢说自己完全理解,只能记录自己理解的部分。

    首先一个二级指针的描述吧

    pp  -->  p  --> data in Mem

    char *p = NULL;

    p = (char *) malloc(10);

    char **pp = NULL;

    pp = &p;

    其次是一个传值与传地址的理解吧,传值就是数据一个copy,传址就是变量在内存中地址传进去,很明显,可以改变地址里的内容,因而传指针和传数组都是能够改变传入的值的。

    #include <stdio.h>
    
    void InPt(char *p)
    {
        printf("InPt p=[%s]	 *p=[%c] 	 &p = [%d]
    ", p, *p, &p);
    }
    
    void InArr(char p[])
    {
        printf("InArr p=[%d]	 p[0]=[%c] 	 &p[0] = [%d]
    ", p, p[0], &p[0]);
    }
    int main(void)
    {
        printf("Hello World!
    ");
    
        char *p1 = "test";//这个是指向常量,分配在静态数据区,妄图改变是不可行的。
        //*p1 = 'C'; error here
    
        char arr[5]= "this";
        char *p = arr;
        printf("Main InArr arr=[%d]	 arr[0]=[%c] 	 &arr[0] = [%d]
    ", arr, arr[0], &arr[0]);
        printf("Main InPt p=[%s]	 *p=[%c] 	 &p = [%d]
    ", p, *p, &p);
    
        printf("*****
    ");
        InArr(arr);
        InPt(p);
    
    
        printf("%s
    ", p);
    
        return 0;
    }
    

     /*************Result:****************/

    Hello World!
    Main InArr arr=[2752167]         arr[0]=[t]      &arr[0] = [2752167]
    Main InPt p=[this]       *p=[t]          &p = [2752160]
    *****
    InArr p=[2752167]        p[0]=[t]        &p[0] = [2752167]
    InPt p=[this]    *p=[t]          &p = [2752144]
    this

     /*************end:****************/

    可以看到  &p = [2752160]      &p = [2752160] 带进去的值是一样,但是装这个值的盒子(内存)却不一样,因为编译器为函数的参数制作值copy,所以我理解,传指针和传数组都是传‘值’,只不过这个值特殊而已,是一个地址而已。

    林博士在《高质量的c及c++编程指南》举得例子:

    void GetMemory(char *p, int num)

    {

        p = (char *)malloc(sizeof(char) * num);

    }

    void Test(void)

    {

        char *str = NULL;

        GetMemory(str, 100);    // str 仍然为 NULL 

        strcpy(str, "hello");   // 运行错误

    }

    分析下GetMemory(str, 100)中str是一个指针,指针是间接取值,自身也占4个字节的空间,所以Test中的&str和GetMemory中的&p是两个盒子,只不过两个盒子中的东西一样而已,这某种意义上是传值,传的是盒子里的内容,指针这里很容易弄乱,至少我是这样的。其返回的任然是装指针的那个盒子,而这盒子并不是和主函数中的盒子一样,所以,分配不成功。

    解决方法1:书中的一个是二级指针,带入chap **p,这样的话把盒子的地址传进去,在带出来.一级p指向data,其地址是二级p的内容,很明显二级就是传的一级指针的地址。

          方法2:返回值传递动态内存

    char *GetMemory3(int num)

    {

        char *p = (char *)malloc(sizeof(char) * num);

        return p;

    }

    void Test3(void)

    {

        char *str = NULL;

        str = GetMemory3(100); 

        strcpy(str, "hello");

        cout<< str << endl;

        free(str); 

    }

    在堆上申请一块地址,p指向其,并返回p的地址。而后str指向这块地址,ok。

    好了睡觉去。

       

  • 相关阅读:
    867-转置矩阵
    704-二分查找
    选择排序
    999-车的可用捕获量
    66-加一
    观察者模式(1)
    命令模式(3)-宏命令
    命令模式(2)-命令接口中的撤销方法
    接口测试
    移动端测试
  • 原文地址:https://www.cnblogs.com/ashen/p/5786032.html
Copyright © 2011-2022 走看看