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]\t *p=[%c] \t &p = [%d]\n", p, *p, &p);
}

void InArr(char p[])
{
    printf("InArr p=[%d]\t p[0]=[%c] \t &p[0] = [%d]\n", p, p[0], &p[0]);
}
int main(void)
{
    printf("Hello World!\n");

    char *p1 = "test";//这个是指向常量,分配在静态数据区,妄图改变是不可行的。
    //*p1 = 'C'; error here

    char arr[5]= "this";
    char *p = arr;
    printf("Main InArr arr=[%d]\t arr[0]=[%c] \t &arr[0] = [%d]\n", arr, arr[0], &arr[0]);
    printf("Main InPt p=[%s]\t *p=[%c] \t &p = [%d]\n", p, *p, &p);

    printf("*****\n");
    InArr(arr);
    InPt(p);


    printf("%s\n", 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。

好了睡觉去。

   

posted @ 2016-08-19 00:26  ashen~  阅读(271)  评论(1编辑  收藏  举报