您的位置:首页 > 编程语言 > C语言/C++

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

2017-04-04 15:51 239 查看
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){
//数组的大小为5
a[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位十六进制

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: