内存区域的划分(复习)
/* 内存区域的划分 1.代码区 存储代码 2.常量区 存储常量 3.全局区(静态全局区) 存储: 1.静态变量 2.全局变量 # include <stdio.h> int c; // 普通全局变量 static int d; // 静态全局变量 int main() { int a; // 普通局部变量 static int b; // 静态局部变量 int c; // 注意这个c不是上面的c,它们只是名字看起来一样而已 a = 10; // 普通局部变量没有默认初始值,所以需要自己赋值 printf("a = %d \n", a); printf("b = %d \n", b); printf("c = %d \n", c); printf("d = %d \n", d); // 通过以上 printf,可以总结规律:静态全局区,默认的初始值为0 // 作用域和生命周期 作用域 生命周期 普通全局变量 当前项目 程序开始到程序结束 静态全局变量 当前文件 程序开始到程序结束 普通局部变量 当前语块 当前语块 静态局部变量 当前语块 程序开始到程序结束 return 0; } 4.栈区 存储:普通局部变量 从定义时系统自动分配内存,离开当前语块系统就会自动回收内存 5.堆区 由程序员手动申请和释放 */
指针与函数
/* 1.指针函数 返回值类型是指针的函数 2.函数指针 指向函数的指针 */
// 1.指针函数 // 下面的代码是一个错误的例子,你能发现它的错误吗? # include <stdio.h> int* test(); // 声明 int main() { int* temp = test(); printf("%d \n", *temp); return 0; } int* test() { int num = 10; int* p = # return p; // 返回了栈区变量的首地址(非常严重的问题!详情见下) } /* 下面的内容是在栈区,当运行完毕,系统会回收其内存资源: int* test() { int num = 10; int* p = # return p; } 当函数返回栈区变量 num 的内存地址之后, 函数运行完毕,系统回收 num 内存,供以后"某某东西"使用 所以,返回的地址不但没有作用,还会导致以后非法访问内存的问题出现 */
// 2.函数指针 /* 函数指针的定义 返回类型说明符 (*函数指针变量名)(参数列表); */ # include <stdio.h> int func(); // 声明 int main() { // 定义函数指针,并进行初始化 int(*p)() = func; // 即:定义了指针p,而且 p 等于 func(func里面存的是函数的首地址) func(); p(); return 0; } int func() { printf("成功执行了 func 函数!\n"); return 6; }
// 函数指针,知识扩展1 # include <stdio.h> int func(); // 声明 typedef int funcType(); // 将 int...() 取别名为 funcType int main() { funcType* p = func; p(); return 0; } int func() { printf("成功执行了 func 函数!\n"); return 6; }
// 函数指针,知识扩展2 # include <stdio.h> int func(int a, int b); // 声明 typedef int(*pfunc)(int a, int b); int main() { pfunc p = func; // 这样也能定义函数指针 int res = p(1,2); printf("%d \n", res); return 0; } int func(int a, int b) { printf("成功执行了 func 函数!\n"); return a + b; }
浙公网安备 33010602011771号