标签:img sizeof 地址 一个 本质 输出 交换 64位 info
本文将介绍二级指针做函数输出以及做函数输入的三种内存模型从内存四区的角度对程序执行的过程进行剖析,通过这中方式来加深对指针的理解。
int main()
{
char *p = NULL;
int len = 0;
getMem(&p, &len);
printf("p=%s\n", p);
FreeMem(&p);
return 0;
}
int getMem(char **myp,int *mylen)
{
char *temp = NULL;
temp = (char*)malloc(100);
if (temp == NULL)
{
return -1;
}
strcpy(temp, "abcdefg");
*mylen = strlen(temp);
*myp = temp;
return 0;
}
*myp = temp;
最初写成了*myp = *temp;
而该表达式赋值两端根本不是一种数据类型。
*myp = temp1;
这句话与*mylen = 某一数值
本质上是一样的,都是*
加上指针变量来改变主调用函数中的内容只不过,myp
为二级指针因此赋值的右端应为一级指针。
"abcdefg"
在常量区中,strcpy(temp, "abcdefg");
这一句使得temp
指向"abcdefg"
,其值为字符‘a‘
的地址。
想要在被调用函数中修改主调用函数中的值,必须使用指针,例如在getMem函数中,修改变量的值使用一级指针,修改一级指针需要用到二级指针。
void FreeMem(char **myp)
{
if (myp == NULL)
{
return;
}
char *tmp = NULL;
tmp = *myp;
free(tmp);
tmp = NULL;
}
void FreeMem(char *myp)
{
if(myp = NULL)
{
return ;
}
free(myp);
}
这两种FreeMem
函数都可以释放p
指向的内存,但第一个函数的好处在于使用了二级指针,可在FreeMem
函数中将主调用函数中的p
的值改为NULL
避免 野指针的出现,而第二个函数则要在FreeMem
后加上一句p=NULL
。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char *myArray[] = { "xcccc","ybbbb","zaaaa" };
int len = sizeof(myArray) / sizeof(myArray[0]);
int i = 0;
for (i = 0; i < len; i++)
{
printf("%s\n", myArray[i]);
//printf("%s\n", *(myArray+i)); 效果相同
}
int j, k;
j = k = 0;
char *temp = NULL;
for (j = 0; j < len - 1; j++)
{
for (k = 0; k < len - j - 1; k++)
{
if (strcmp(myArray[k], myArray[k + 1]) > 0)
{
temp = myArray[k];
myArray[k] = myArray[k + 1];
myArray[k + 1] = temp;
}
}
}
for (i = 0; i < len; i++)
{
printf("%s\n", myArray[i]);
//printf("%s\n", *(myArray+i)); 效果相同
}
return 0;
}
1.在32位操作系统下指针变量的长度为4,在64位下为8。
2.指针数组为元素为指针的数组,myArray
数组中有三个元素,sizeof(myArray) / sizeof(myArray[0])
可以求出数组长度。
3.排序使用的为最简单的冒泡排序。排序过程中交换的是指针而不是内存块。
int main()
{
char *myArray[] = { "zzz","yyyyyyy","xxxxxxxxx" };
int len = sizeof(myArray) / sizeof(myArray[0]);
printArray(myArray, len);
SortArray(myArray, len);
printArray(myArray, len);
return 0;
}
void printArray(char **myArray, int len)
{
for (int i = 0; i < len; i++)
{
printf("%s\n", myArray[i]);
}
}
void SortArray(char **myArray, int len)
{
char *temp = NULL;
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
if (strcmp(myArray[j], myArray[j + 1]) > 0)
{
temp = myArray[j];
myArray[j] = myArray[j + 1];
myArray[j + 1] = temp;
}
}
}
}
数组在做函数参数是退化为指针,数组名指向数组的第一个元素,即数组名中存放的是数组中第一个元素的地址。指针数组也是如此,char *myArray[];
中定义了一个名为myArray
的指针数组,根据上面的说明,myArray
为第一个元素的地址,而数组元素为指向char
类型的指针,即为char *
类型,因此myArray
为char **
类型,所以在函数中第一个参数,均为char **myArray
。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char myArray[10][30] = { "ddddd","ccccc","bbbbb","aaaaa" };
int num = 4;
for (int i = 0; i < num; i++)
{
printf("%s\n", myArray[i]);
}
char temp[30];
for (int i = 0; i < num - 1; i++)
{
for (int j = 0; j < num - 1 - i; j++)
{
if (strcmp(myArray[j], myArray[j + 1]) > 0)
{
strcpy(temp, myArray[j]);
strcpy(myArray[j], myArray[j + 1]);
strcpy(myArray[j + 1], temp);
}
}
}
for (int i = 0; i < num; i++)
{
printf("%s\n", myArray[i]);
}
return 0;
}
int main()
{
char myArray[10][30] = { "ddddd","ccccc","bbbbb","aaaaa" };
int num = 4;
printArray(myArray, num);
SortArray(myArray, num);
printArray(myArray, num);
return 0;
}
void printArray(char (*myArray)[30], int len)
{
for (int i = 0; i < len; i++)
{
printf("%s\n", myArray[i]);
}
}
void SortArray(char (*myArray)[30], int len)
{
char temp[30];
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
if (strcmp(myArray[j], myArray[j + 1]) > 0)
{
strcpy(temp, myArray[j]);
strcpy(myArray[j], myArray[j + 1]);
strcpy(myArray[j + 1], temp);
}
}
}
}
二维数组在做函数参数的时候会退化成为一个指针数组。
二维数组中重要的两个点:
1.二维数组名为第一维首元素的地址。
2.一维数组名为首元素的地址。
有了这两点下面将演示如何用数组名打印某一个元素:
==> 表示等价
myArray ==> &myArray[0] //上面的第一点
myArray + 2 ==> &myArray[2]
*(myArray + 2) ==> myArray[2] ==> &myArray[2][0] //上面的第二点
*(myArray + 2) + 1 ==> &myArray[2][1]
*(myArray + 2) + 4 ==> &myArray[2][4]
*(*(myArray + 2) + 4) ==> myArray[2][4]
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char **p = NULL;
int num = 4;
p = (char**)malloc(sizeof(char*)*num);
for (int i = 0; i < num; i++)
{
p[i] = (char*)malloc(sizeof(char) * 100);
sprintf(p[i], "%d%d%d", 4 - i, 4 - i, 4 - i);
}
for (int i = 0; i < num; i++)
{
printf("%s\n", p[i]);
}
char *temp = NULL;
for (int i = 0; i < num - 1; i++)
{
for (int j = 0; j < num - i - 1; j++)
{
if (strcmp(p[j], p[j + 1]) > 0)
{
temp = p[j];
p[j] = p[j + 1];
p[j + 1] = temp;
}
}
}
for (int i = 0; i < num; i++)
{
printf("%s\n", p[i]);
}
for (int i = 0; i < num; i++)
{
if (p[i] != NULL)
{
free(p[i]);
p[i] = NULL;
}
}
if (p != NULL)
{
free(p);
p = NULL;
}
return 0;
}
int main()
{
int num = 4;
char **p = NULL;
//p = getMem(num);
getMem_1(&p, num); //两种方式
printArray(p, num);
SortArray(p, num);
printArray(p, num);
myArrayFree(p, num);
return 0;
}
char **getMem(int num)
{
char **p = NULL;
p = (char**)malloc(sizeof(char*)*num);
for (int i = 0; i < num; i++)
{
p[i] = (char*)malloc(sizeof(char) * 100);
sprintf(p[i], "%d%d%d", 4 - i, 4 - i, 4 - i);
}
return p;
}
int getMem_1(char ***p, int num)
{
if (p == NULL)
{
return -1;
}
char **temp = NULL;
temp = (char**)malloc(sizeof(char*)*num);
for (int i = 0; i < num; i++)
{
temp[i] = (char*)malloc(sizeof(char) * 100);
sprintf(temp[i], "%d%d%d", 4 - i, 4 - i, 4 - i);
}
*p = temp;
return 0;
}
void printArray(char **myArray, int len)
{
for (int i = 0; i < len; i++)
{
printf("%s\n", myArray[i]);
}
}
void SortArray(char **myArray, int len)
{
char *temp = NULL;
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
if (strcmp(myArray[j], myArray[j + 1]) > 0)
{
temp = myArray[j];
myArray[j] = myArray[j + 1];
myArray[j + 1] = temp;
}
}
}
}
void myArrayFree(char **p,int len)
{
for (int i = 0; i < len; i++)
{
if (p[i] != NULL)
{
free(p[i]);
p[i] = NULL;
}
}
if (p != NULL)
{
free(p);
p = NULL;
}
}
标签:img sizeof 地址 一个 本质 输出 交换 64位 info
原文地址:https://www.cnblogs.com/optimjie/p/12252698.html