C语言中的二级指针的三种内存模型

来源:互联网 发布:四川大学软件学院课程 编辑:程序博客网 时间:2024/04/30 05:50

C语言中的指针用的是比较多,一级指针和二级指针时最常见的。其中,在C语言中二级指针相对于一级指针要难一些,下面就介绍一下C语言中二级指针的三种内存模型。

一、二维数组char a[5][5]内存模型

#include<stdio.h>#include<malloc.h>#include<string.h>/*C语言中的二级指针的三种内存模型*///第一种模型,二维数组char a[5][5]void func1(){//二维数组,表示有5个大小为5的字符串(实际上这个字符串的大小只能为4,因为最后一位用来存储'\0'表示结束)char a[5][5] = { "zxcv", "mnbv", "gbde", "abde", "1234"};//如果字符的长度为5,如"abcde"就会导致,a[0]为"abcde1234",因为相当于你用字符'e'代替了'\0'//对二维数组a进行排序,由小到大//交换它们的内容,利用冒泡排序char temp[5] = {0};for (int i = 0; i < 5;i++){for (int j = 0; j < 5 - i - 1;j++){//前面的大于后面的就交换他们的内容if (strcmp(a[j],a[j+1]) > 0){strcpy(temp,a[j]);strcpy(a[j],a[j+1]);strcpy(a[j+1],temp);}}}for (int i = 0; i < 5;i++){printf("a:%s\n",a[i]);}}
下面给一个内存图,便于理解,上面的二维数组的内存是在栈中分配的,是一个5行5列的二维数组。因为,这是一个二维字符数组,其实就等价于5个字符串,大小为5(包括'\0')。栈的开口是向下的,一般都是开口向下的栈(地址由高到低,避免栈溢出),当然也有向上的。至于,为什么栈开口向下可以避免溢出,这个原因的话就要从操作系统原理来说了,有兴趣可以自己去学一下,这里就不讨论了。


二、一维指针数组char* a[5]内存模型

void func2(){//一维指针数组,数组中是一级指针char* a[3] = {0};//给数组中的指针开辟空间for (int i = 0; i < 3;i++){if (a[i]==NULL){//数组的大小为5a[i] = (char*)malloc(5 * sizeof(char));}}//给数组赋值strcpy(a[0], "1234");//给a[0]赋值的时候,需要注意,不要a[0]="abcd",不然后面使用strcpy的时候会报异常//原因,因为,如果你这样赋值,相当于"abcd"是一个常量区中的字符串,只是后把,这个字符串的首地址给a[0],//你是无法改变常量区中的内容strcpy(a[1], "avxd");strcpy(a[2], "zcsa");//对二维数组a进行排序,由大到小进行排序//第一种,交换它们的内容,利用冒泡排序char temp[5] = { 0 };for (int i = 0; i < 3; i++){for (int j = 0; j < 3 - i - 1; j++){//前面的大于后面的就交换他们的内容if (strcmp(a[j + 1], a[j]) > 0){//这里交换的是指针所指向的内容strcpy(temp, a[j]);strcpy(a[j], a[j + 1]);strcpy(a[j + 1], temp);}}}for (int i = 0; i < 3;i++){printf("a:%s\n",a[i]);}strcpy(a[0], "2341");strcpy(a[0], "a341");strcpy(a[0], "z341");//第二种,交换它们的地址,利用冒泡排序char* ptemp = NULL;for (int i = 0; i < 3; i++){for (int j = 0; j < 3 - i - 1; j++){//前面的大于后面的就交换他们的内容if (strcmp(a[j + 1], a[j]) > 0){//这里交换的是指针的值ptemp = a[j];a[j] = a[j + 1];a[j + 1] = temp;}}}for (int i = 0; i < 3; i++){printf("a:%s\n", a[i]);}}
一维指针数组内存模型图,这个地址我是随便写的


三、二级指针char** p内存模型

void func3(){char **a = NULL;a = (char**)malloc(sizeof(char*)*3);for (int i = 0; i < 3;i++){a[i] = (char*)malloc(sizeof(char)*5);}strcpy(a[0],"1234");strcpy(a[1],"abcd");strcpy(a[2],"mnnm");//对二维数组a进行排序,由大到小进行排序//第一种,交换它们的内容,利用冒泡排序char temp[5] = { 0 };for (int i = 0; i < 3; i++){for (int j = 0; j < 3 - i - 1; j++){//前面的大于后面的就交换他们的内容if (strcmp(a[j + 1], a[j]) > 0){//这里交换的是指针所指向的内容strcpy(temp, a[j]);strcpy(a[j], a[j + 1]);strcpy(a[j + 1], temp);}}}for (int i = 0; i < 3; i++){printf("a:%s\n", a[i]);}strcpy(a[0], "1234");strcpy(a[1], "9898");strcpy(a[2], "abcd");//对二维数组a进行排序,由大到小进行排序//第二种,交换它们的地址,利用冒泡排序char* p = (char*)malloc(sizeof(char)*5);for (int i = 0; i < 3; i++){for (int j = 0; j < 3 - i - 1; j++){//前面的大于后面的就交换他们的内容if (strcmp(a[j+1],a[j]) > 0){//这里交换的是指针所指向的内容p = a[j];a[j] = a[j + 1];a[j + 1] = p;}}}for (int i = 0; i < 3; i++){printf("a:%s\n", a[i]);}}

二级指针内存模型图,地址是随便写的一个8位十六进制


0 0