//内存分区:栈区,堆区,全局区
栈区
//栈区:编译器自动分配释放 //生命周期,函数调用存在,函数调用结束:销毁
int* myFuc()
{
int a = 10;
return &a;
}
void test05()
{
int* p = myFuc();
printf("*p=%d\n", *p);
printf("*p=%d\n", *p);
printf("*p=%d\n", *p);
printf("*p=%d\n", *p);
}
char* getString()
{
char str[] = { "Hello world!" };
return str;
}
void test06()
{
char* p = NULL;
p = getString();
//printf("*p=%s\n", *p);
}
堆区
对比 (int* p) (int**p)
(1) allocateSpace(int* p)
//2. 通过函数参数的方式,带出申请的空间
void allocateSpace(int* p)
{
p = (int*)malloc(sizeof(int) * 5);
if (p == NULL)
{
return;
}
memset(p, 0, 5);
}
void test08()
{
int* ret = NULL;
allocateSpace(ret);
printf("ret = %p", ret);
//for (int i = 0; i < 5; i++)
//{
// ret[i] = i + 100;
//}
//for (int i = 0; i < 5; i++)
//{
// printf("%d ", ret[i]);
//}
free(ret);
ret = NULL;
}
(2) allocateSpace2(int** p)
//修改:让通过参数的方式可以带出,堆的空间
void allocateSpace2(int** p) //形参p指向-实参ret的地址
{
int* temp = (int*)malloc(sizeof(int) * 5);
if (temp == NULL)
{
return;
}
memset(temp, 0, 5);
*p = temp; //修改的形参p解引用,指向的实参ret的值
}
void test09()
{
int* ret = NULL;
allocateSpace2(&ret);
printf("ret = %p\n", ret);
for (int i = 0; i < 5; i++)
{
ret[i] = i + 100;
}
for (int i = 0; i < 5; i++)
{
printf("%d ", ret[i]);
}
free(ret);
ret = NULL;
}
全部代码
//堆区:手动申请,手动释放
//一个函数申请空间,一个函数释放空间
//1.通过返回值的方式,带出申请的空间
int* getSpace()
{
int* p = (int*)malloc(sizeof(int) * 5);
if (p == NULL)
{
return NULL;
}
for (int i = 0; i < 5; i++)
{
p[i] = i + 100;
}
return p;
}
void test07()
{
int* ret = getSpace();
for (int i = 0; i < 5; i++)
{
printf("%d ", *(ret + i));
}
printf("\n");
//
free(ret);
ret = NULL;
}
//----------------------------------------------------
//2. 通过函数参数的方式,带出申请的空间
void allocateSpace(int* p)
{
p = (int*)malloc(sizeof(int) * 5);
if (p == NULL)
{
return;
}
memset(p, 0, 5);
}
void test08()
{
int* ret = NULL;
allocateSpace(ret);
printf("ret = %p", ret);
//for (int i = 0; i < 5; i++)
//{
// ret[i] = i + 100;
//}
//for (int i = 0; i < 5; i++)
//{
// printf("%d ", ret[i]);
//}
free(ret);
ret = NULL;
}
//修改:让通过参数的方式可以带出,堆的空间
void allocateSpace2(int** p) //形参p指向-实参ret的地址
{
int* temp = (int*)malloc(sizeof(int) * 5);
if (temp == NULL)
{
return;
}
memset(temp, 0, 5);
*p = temp; //修改的形参p解引用,指向的实参ret的值
}
void test09()
{
int* ret = NULL;
allocateSpace2(&ret);
printf("ret = %p\n", ret);
for (int i = 0; i < 5; i++)
{
ret[i] = i + 100;
}
for (int i = 0; i < 5; i++)
{
printf("%d ", ret[i]);
}
free(ret);
ret = NULL;
}
//test08() //形参带出堆区内存,int*p
//带不出来, p (直接在p上修改)
//test09(); //形参带出堆区内存, int**p
//能带出来, *p = temp(在p所指向的实参ret中,修改)
全局区
//全局区
extern int sum = 100; //外部链接 ---> 其他文件也能用,这个变量
static int c = 200; //内部链接 ---> 只有当前文件能用,这个变量
void test10()
{
//声明:告诉编译器这个符号(g_a)是存在的,让我先用
//让我先编译通过,让链接器去找这个符号
extern int g_a;
printf("g_a=%d\n", g_a);
//常量字符串是否可以修改
//取决于编译器
//vs 字符串常量的地址,同文件和不同文件是一样的,so不可以修改
//qt,devC++, 同文件是相同的,不同文件不同
//
//char* p = { "hello world!" }; //报错:"const char *" 类型的值不能用于初始化 "char *" 类型的实体
const char* p = { "hello world!" };
//p[2] = 'j'; //不可以修改
char p2[] = "hello world!"; //正确:栈里面,修改的自己的变量, 而不是去修改常量"hello world!"
p2[1] = 'j'; //可以修改
}