有同事今天问我一个指针的问题,没深究原因,下班回来静下心来分析分析,写下这篇文章,如有任何疑问请留言.

问题一

要实现一个函数,我们姑且理解成函数内部 malloc申请一块内存,然后针对这块内存做一系列操作,操作这部分姑且不用实现,我们要返回申请的这片内存的地址.

version 1

如果你拿到这个问题就立刻编写代码的话极有可能这么写:

/*
    Name: 二级指针
    Copyright: 52coder.net
    Author: 52coder
    Date: 03/06/17 17:24
    Description: pointer
 */

#include <stdio.h>
#include <stdlib.h>

/*获取malloc内存的地址*/
int getaddress(int *address)
{
    int size = 64;
    address = malloc(size *sizeof(int));
    printf("Address of malloc memory is:%p\n",address);
    return 0;
}
int main()
{
    int *pointer = NULL;
    getaddress(pointer);
    printf("Address of pointer is:%p\n",pointer);
    return 0;
}

那么结果可能比较让人失望:

Address of malloc memory is:0x100500270
Address of pointer is:0x0
Program ended with exit code: 0

pointer 的值居然是0x0,换言之我们没有将所申请内存的地址带出来.

version 2

/*
    Name: 二级指针
    Copyright: 52coder.net
    Author: 52coder
    Date: 03/06/17 17:24
    Description: pointer
 */

#include <stdio.h>
#include <stdlib.h>

/*获取malloc内存的地址*/
int getaddress(int **address)
{
    int * tmp = NULL;
    int size = 64;
    tmp = malloc(size *sizeof(int));
    *address = tmp;
    printf("Address of malloc memory is:%p\n",tmp);
    return 0;
}
int main()
{
    int *pointer = NULL;
    getaddress(&pointer);
    printf("Address of pointer is:%p\n",pointer);
    return 0;
}

输出结果终于符合我们预期:
Address of malloc memory is:0x100202350
Address of pointer is:0x100202350
Program ended with exit code: 0

pointer的值就是我们在函数中所申请的内存地址.
那么写道这里你是否会有疑问,函数getaddress中是否真正需要tmp中间变量呢?

version 3

/*
    Name: 二级指针
    Copyright: 52coder.net
    Author: 52coder
    Date: 03/06/17 17:24
    Description: pointer
 */

#include <stdio.h>
#include <stdlib.h>

/*获取malloc内存的地址*/
int getaddress(int **address)
{
    int size = 64;
    *address = malloc(size *sizeof(int));
    printf("Address of malloc memory is:%p\n",address);
    return 0;
}
int main()
{
    int *pointer = NULL;
    getaddress(&pointer);
    printf("Address of pointer is:%p\n",pointer);
    return 0;
}

运行结果居然是:
Address of malloc memory is:0x7fff5fbff7b0
Address of pointer is:0x100300000
Program ended with exit code: 0
那么为什么会是这样呢?
问题原因很简单,就是在函数getaddress中我们打印*address才是申请内存的地址.

问题二

这个同样是一道考验指针的问题,大致要实现如下内容,结构体中包含二级指针,通过二级指针 一级指针都可以访问新申请的内存.

/*
    Name: 二级指针
    Copyright: 52coder.net
    Author: 52coder
    Date: 03/06/17 17:24
    Description: pointer
 */

#include <stdio.h>
#include <stdlib.h>

typedef struct student
{
    int age;
    int height;
}stu;

typedef struct school
{
    int num;
    stu **boys;
}grade;

int main()
{
    int i = 0;
    stu *tmp = NULL;
    grade oneclass;
    
    //定义班级男生个数
    oneclass.num = 55;
    
    grade *one = &oneclass;
    
    //申请内存
    tmp = malloc(oneclass.num * sizeof(stu));
    
    one->boys = &tmp;
    
    //打印三种操作方法对应的地址
    for (i = 0; i < 55; i++)
    {
        printf("tmp + i =%p &tmp[i] = %p *one->boys+i =%p\n",
                tmp+i, &tmp[i], *(one->boys)+i);
    }
    
    //设置55个元素的age
    for (i=0; i<55; i++)
    {
        tmp[i].age = i;
    }
    //设置55个元素的height
    for (i=0; i<55; i++)
    {
        tmp[i].height = 55-i;
    }

    for (i=0; i<55; i++)
    {
        printf("%d ", (*(one->boys))[i].age);
    }
    
    for (i=0; i<55; i++)
    {
        printf("%d ", (*one->boys)[i].height);
    }
    
    return 0;
}

下面代码是一段验证程序

/*
    Name: 二级指针
    Copyright: 52coder.net
    Author: 52coder
    Date: 03/06/17 17:24
    Description: pointer
*/

#include <stdio.h>
#include <stdlib.h>

typedef struct student
{
    int age;
    int height;
}stu;

typedef struct school
{
    int num;
    stu **boys;
}grade;

int main()
{
    int i = 0;
    stu *tmp = NULL;
    grade oneclass;
    
    //定义班级男生个数
    oneclass.num = 55;
    
    grade *one = &oneclass;
    
    //申请内存
    tmp = malloc(oneclass.num * sizeof(stu));
    
    one->boys = &tmp;
    
    printf("\n");
    
    //验证地址与值的关系
    printf("&tmp = %p,one->boys = %p\n",&tmp,one->boys);
    printf("tmp = %p,*(one->boys) = %p\n",tmp,*(one->boys));
    printf("tmp + 10 = %p,*(one->boys) + 10 = %p\n",tmp+10,*(one->boys)+10);

    return 0;
}