c语言 -> 二级指针三种内存模型

说到二级指针,不少刚入门的朋友应该都会和我一样感到十分的头疼;明明一级指针就够我受的,
咋又整个二级指针呢???

二级指针无论是理解还是运用对于我这种刚入门的菜鸟是非常困难的;所以,我特意在网上找了些
资料,然后把他们整合到一起,和大家分享下:

二级指针主要分成三种内存模型:
1. 第一种内存模型 :指针数组;指针指向栈区的一段内存的首地址,并且在栈区分配内存空间,每个元素里又
装有一个指针指向常量区的某一地址,类似于char*myArray[]={"aaaaa","cccccc","bbbbbb","11111"};

贴上一段代码直观感受下:
void sortmyArray(char **myArray, int num)
{
    int i =0, j = 0;
    char *tmp = NULL;
    //排序
    for(i = 0; i < num ; i++)
    {
        for(j = i; j < num; j++)
        {
            if(strcmp(myArray[i], myArray[j]) > 0)
            {
                tmp = myArray[i];       //交换的是数组元素,交换的是指针的值
                myArray[i] = myArray[j];
                myArray[j] = tmp;
            }
        }
    }
}
int main()
{
    int i = 0, j = 0;
    int num = 0;
    char *tmp = NULL;
    char * myArray[] = {"aaaaa", "cccccc", "bbbbbb", "11111"};

    //打印
    num = sizeof(myArray)/sizeof(myArray[0]);
    printf("排序之前:\n");
    printmyArray(&myArray, num);
    //排序
    sortmyArray(myArray, num);


    //打印
     printf("排序之后:\n");
    printmyArray(&myArray, num);
    return 0;
}
第二种内存模型:二维数组;我们在学习二维数组的时候,会了解到一个行指针变量的概念,
行指针是指向某一行首元素的一个指针变量,一行内又有多个元素,我们可以把这一行的元素
看作是在一段内存里,那么行指针就指向这段内存空间。换句话说,我的二维数组的数组名是
一个指针,它又指向了行指针,行指针又指向了一段内存空间,那么是不是和二级指针有些相似??

二级指针第二种内存模型和二级指针第一种内存模型本质区别是myArray + 1 的长度不一样
也就是指针的步长不一样, 指针指向的内存空间数据类型不一样

void printmyArray(char myArray[10][30], int num)
{
    int i =0;
    for(i = 0; i < num; i++)
    {
        //printf("%s\n", myArray[i]);   //更符合程序员的看法
        printf("%s\n", *(myArray + i)); //编译器的做法

    }
}

//交换的是内存块
void sortmyArray(char myArray[10][30], int num)
{
    int i = 0, j = 0;
    char myBuf[30];
    char tmpBuf[30];
    for(i = 0; i < num; i++)
    {
        for(j = i + 1; j < num; j++)
        {
            if(strcmp(myArray[i], myArray[j]) > 0)
            {
                strcpy(tmpBuf, myArray[i]);//交换的是内存块
                strcpy(myArray[i], myArray[j]);
                strcpy(myArray[j], tmpBuf);
            }
        }
    }

}
int main()
{

    int num = 4;

    char myArray[10][30] = {"aaaaaa", "cccccc", "bbbbbbb", "11111"};

    //myArray: 编译器只关心有10行, 每行30列
    //myArray + 1, 多维数组名的本质
    int len1 = sizeof(myArray);
    int len2 = sizeof(myArray[0]);
    int size = len1 / len2;
    printf("len1 = %d, len2 = %d, size = %d\n", len1, len2, size);
    //打印
    printf("排序之前:\n");
    printmyArray(myArray, num);

    //排序, 交换
    sortmyArray(myArray, num);

    //打印
    printf("排序之后:\n");
    printmyArray(myArray, num);
    return 0;
}

第三种内存模型:一个指针指向用malloc分配一段内存空间,每个元素内保存一个指针变量,每个指针变量又
指向一段内存空间;第三种内存模型和前两种最大的不同是它的存储位置

char **getMem(int num)
{
    int i = 0;
    char **p2 = NULL;
    p2 = (char **)malloc(sizeof(char*) *num);    //堆区里开辟一个数组,数组里每个元素装着一个指针
    if(p2 == NULL)
    {
        return NULL;
    }
    for(i = 0; i < num; i++)
    {
        p2[i] = (char*)malloc(sizeof(char) *100); //数组中每个指针指向一块内存空间
        sprintf(p2[i], "%d%d%d%d", i + 1, i + 1, i + 1, i + 1);
    }
    return p2;
}

void sortmyArray(char **myArray, int num)
{
    int i =0, j = 0;
    char *tmp = NULL;
    //排序
    for(i = 0; i < num ; i++)
    {
        for(j = i; j < num; j++)
        {
            if(strcmp(myArray[i], myArray[j]) > 0)
            {
                tmp = myArray[i];       //交换的是数组元素,交换的是指针的值
                myArray[i] = myArray[j];
                myArray[j] = tmp;
            }
        }
    }
}
void printmyArray(char **myArray, int num)
{
    int i =0;
    for(i = 0; i < num; i++)
    {
        //printf("%s\n", myArray[i]);   //更符合程序员的看法
        printf("%s\n", *(myArray + i)); //编译器的做法

    }

}

void getMem_free(char **p2, int num)
{
    int i =0;
    //释放内存
    for(i = 0; i < num; i++)
    {
        if(p2[i] != NULL)
        {
            free(p2[i]);
            p2[i] = NULL;
        }
    }
    if(p2 != NULL)
    {
        free(p2);
    }
}
int main()
{
    int i = 0, j = 0;
    char *tmp = NULL;
    char **p2 = NULL;
    int num = 5;
    char tmpBuf[100];
    p2 = getMem(num);

    //打印
    printf("排序之前:\n");
    printmyArray(p2, num);

    //排序
    sortmyArray(p2, num);

    //打印
    printf("排序之后:\n");
    printmyArray(p2, num);

    getMem_free(p2, num);
    return 0;
}


猜你喜欢

转载自blog.csdn.net/desporado/article/details/80377003