资讯动态

第15天 C语言复习 2

发布时间:2026/8/23 7:41:10 来源:尧图企业网站定制
一.内存泄漏和内存溢出1.内存泄漏内存泄漏申请了内存但忘记释放可用内存慢慢变少慢。free()发生位置堆区。释放free(p);p NULL;2.内存溢出内存溢出向内存中写入了超出边界的数据破坏相邻内存快速。发生位置堆、栈、全局区都可能栈区 高地址 函数形参局部变量未使用区堆区 malloc,calloc,realloc动态分布静态区:静态未初始化区默认为0静态初始化区非0常量区 字符串字面量、const 常量常量区.rodata存放字符串字面量const全局常量枚举常量只读数据文本区低地址代码区常量区有的资料叫.rodata只读数据段有的归在代码段Text中本质是只读内存。二.函数1.函数作用同一个函数可以被多次调用而不需要重复写相同的代码。函数声明通常写在 main() 函数之前或者头文件中。返回类型函数名(参数类型参数名, ...);函数定义返回类型 函数名(参数类型 参数名, ...){// 函数体执行的操作return 返回值; // 如果有返回值}函数调用在 main() 函数或其他函数中通过函数名调用函数并传递参数。2.函数的参数1 . 形参形式参数形参是函数定义中声明的参数本身在函数定义时没有具体的值。形参是局部变量仅在函数的执行过程中有效函数结束后形参就被销毁。2. 实参实际参数实参可以是常量、变量、表达式等。当调用函数时实参的值会被复制给形参函数执行时使用这些值。实参可以在函数外部定义并且在函数调用后它们的值不会被形参的操作改变除非通过指针或引用方式传递。3.形参和实参的关系在函数调用过程中实参的值被按值传递给形参。这意味着实参的值被复制到形参中函数内的任何操作都不会影响到实参本身。形参的变化不影响实参除非使用指针或特殊方式传递。4.指针与引用传递的例外使用指针作为形参时可以让函数修改实参的值。通过解引用操作 (*) 可以修改了实参按值传递是将变量的值复制到函数中而指针传递是将变量的内存地址传递给函数使得函数可以直接修改原始数据。3.递归函数递归函数是一种直接或间接调用自身的函数。基线条件Base Case递归终止的条件当满足该条件时递归停止避免无限循环。递归步骤Recursive Step在每次递归调用时问题被分解为一个或多个更小的问题。返回类型 函数名 函数参数return_typefunction_name(parameters) //parameters函数参数{if (base_case_condition) //终止条件{// 基线条件终止递归 return base_case_value;}else{// 递归步骤继续调用函数自身 return function_name(smaller_problem);}}4.goto语句goto语句用于无条件跳转到程序中的标签位置通常用于跳出多重循环等情形。goto 只能在同一函数内部跳转不能跨函数跳转。gotolabel; // 直接跳转到标签位置... label:// 定义标签位置// 代码块其中label是一个标识符用于标记目标位置可以出现在同一函数中的任何地方。int func (void);表示一个返回整数类型值的无参数函数。#include file.c 用于将一个源文件包含到另一个源文件中C 语言中函数只能返回一个值虽然可以通过指针、结构体等方式间接返回多个值但不能直接返回多个值。通过指针参数函数可以修改外部变量的值。array[]表示的是数组类型不能作为函数的返回类型。静态函数在定义的文件内有效不能被外部文件调用作用域局限于所在文件传递结构体给函数结构体可以通过值传递或指针传递给函数。值传递会复制整个结构体指针传递则只传递结构体的地址。#include可以用于引入头文件也可以用于引入源文件三.指针1.指针指针是一个变量它存储另一个变量的内存地址int a10;int *pa; //a 获取变量 a 的内存地址。int *p 声明了一个指向 int 类型的指针变量 p。p 存储了 a的地址。p a; // 将 a 的地址赋给指针 p解引用int 变量名*p // 通过解引用访问指针 p 指向的变量 a 的值2.指针的算术运算指针进行加法运算时指针会移动到它所指向类型的下一个元素位置加法运算的步长取决于指针所指向数据 类型的大小。sizeof(int)字节p 实际上将 p 移动了 sizeof(int) 个字节p 指向的是 int 类型的数组元素。指针相减:两个指针指向同一个数组中的元素则它们的差值表示两个元素之间的距离以元素为单位而不是字节为单位。3.二级指针指针的指针指针的指针简单来说就是一个存储另一个指针地址的变量。int a5;int *pa; //指针p 指向 变量a 的地址int **ppp; //指针pp指向指针p的地址指针的指针常用于动态分配二维数组。在二维数组的分配中我们可以使用指针数组来存储每一行的地址指针的指针可以作为整个二维数组的入口。在函数中修改一个指针的值需要使用指针的指针。在函数中修改传入的指针本身的地址而不是指针指向的数据就需要使用指针的指针。4.指针常量与常量指针1.常量指针常量指针是指指向常量数据的指针即通过该指针不能修改它所指向的数据。const 数据类型 * 指针名 const 修饰的是指针所指向的数据类型表示指向的数据是常量。const int *pa;pa; 可以修改指针指向别的地址2.指针常量指针常量是指指针本身的值不可修改但可以修改指向的数据。 数据类型 * const 指针名int *const pa;*p20; //改变指向的值。5.指针数组与数组指针1.一维数组与指针的关系数组名是一个指针常量指向数组的第一个元素。通过*(p 1)可以访问数组的下一个元素。通过指针运算如p或p p 1可以改变指针指向的内存地址。2.指针数组指的是一个数组其元素是指针数据类型 * 数组名【】int *arr[5] //一个包含 5 个指向 int 类型数据的指针数组3.数组指针数组指针是一个指针它指向一个完整的数组而不是数组中的单个元素。数据类型 *指针名 数组名【数组长度】int (*p) arr[5] //数组指针指向一个包含5个int元素的数组。*arr和arr[0]都表示数组的第一个元素6.指针函数与函数指针1.指针函数指针函数是指返回类型为指针的函数返回类型 * 函数名 变量int *p( )返回 int *2.函数指针函数指针是指向函数的指针。函数指针可以存储函数的地址从而通过指针来调用该函数。返回类型 *函数名 (参数列表);函数指针可以作为函数的参数函数指针可以存储在数组中用于处理多个函数7.野指针野指针是指向无效内存地址的指针。通常由于指针指向的内存已经被释放、未正确初始化或超过其作用域。野指针的使用会导致未定义行为包括程序崩溃、内存泄漏甚至安全漏洞 如缓冲区溢出、代码注入等当指针声明时未赋予初始值它会指向一个随机的内存地址。当指针指向的内存被释放后该指针依然保留了原来的地址但该地址已经不再有效成为野指针int *ptr (int *)malloc(sizeof(int));*ptr 10;free(ptr); // 释放了指针指向的内存*ptr 20; // 错误ptr 现在是野指针2.野指针的规避方法1.声明指针时将指针初始化为NULL2.释放动态内存后立即将指针置为 NULL避免误使用已经释放的指针3.确保每块内存只调用一次 free()。8.动态内存分布动态分布在堆区所在文件 stdlib.h函数malloc 返回类型*malloc (申请的字符数)(int *)malloc(sizeof(int))申请内存空间并返回。申请的空间未初始化。常用memset初始化返回值指向分配内存的指针失败返回NULLcalloc:动态分配内存并自动初始化为 0返回类型* calloc (分配的个数每个元素的大小(字节))(int *) calloc (size_t num, size_t size)返回值指向分配内存的指针失败返回NULLrealloc:扩充或缩小重新调整已分配内存块的大小的函数返回类型* realloc 返回类型 *p, size_tnew_sizep: 指向之前由malloc、calloc或realloc分配的内存块可以是 NULL(int*) realloc (int *ptr, size_t new_size);返回值指向分配内存的指针失败返回NULLfree:只能释放动态分配的内存free(p)

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价