![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C语言
文章平均质量分 72
xiebs_
我对不起唐老师
展开
-
48、函数设计原则
1、函数设计原则函数从意义上应该是一个独立的功能模块函数名要在一定程度上反映函数的功能函数参数名要能够体现参数的意义尽量避免在函数中使用全局变量当函数参数不应该在函数体内部被修改时,应该加上const声明如果参数是指针,且仅作输入参数,则应加上const声明不能省略返回值的类型— 如果函数没有返回值,应该声明为 void 类型对参数进行有效性的检查·— 对于指针参数的检查尤为...原创 2019-08-11 20:10:03 · 170 阅读 · 0 评论 -
35、函数与指针分析
1、函数类型C语言中的函数有自己特定的类型函数的类型由返回值 ,参数类型和参数个数共同决定比如int add(int i,int j)的类型为 int(int,int)C语言中通过typedef为函数类型重命名比如typedef type name(parameter list)typedef int f(int,int);typedef void p(int);2、函数指针...原创 2019-08-08 20:57:14 · 170 阅读 · 0 评论 -
34、数组参数和指针参数分析
1、思考为什么C语言的数组参数会退化为指针?退化的意义:C语言中只会以值拷贝的方式传递参数当向函数传递数组时— 将整个数组拷贝一份传入函数(×)— 将数组名看做常量指针传数组首元素地址C语言以高效作为最初设计目标:a)参数传递的时候如果拷贝整个数组执行效率将大大下降b)参数位于栈上,太大的数组拷贝将导致栈溢出。2、二维数组参数二维数组参数同样存在退化的问题— 二维数组...原创 2019-08-08 17:41:34 · 151 阅读 · 0 评论 -
33、多维数组和多维指针
1、指向指针的指针指针的本质是变量指针会占用一定的内存空间可以定义指针的指针来保存指针变量的地址值#include <stdio.h>int main(){ int i = 0; int *p = NULL; int** pp = NULL; pp = &p; *pp = &i; return 0;}2、问题为什么需要指向指...原创 2019-07-19 08:43:16 · 152 阅读 · 0 评论 -
32、main函数和命令行参数
1、main函数的概念原创 2019-07-18 21:20:01 · 174 阅读 · 0 评论 -
31、数组指针和指针数组分析
1、思考下面这些声明合法吗?int array[5];int matrix[3][3];int* pa = array;int* pm = matrix;问题:array代表数组首元素地址,那么matrix代表什么?array和&array的地址值相同,但是意义不同,那么他们代表的类型相同吗?...原创 2019-07-11 21:55:49 · 107 阅读 · 0 评论 -
30、数组、字符数组以及字符串定义
常规的在定义数组时,一般都是 int a[5] = { 0 };代表5个元素都是0对于字符数组,char ca[] = { '0' };int main(){ char c[5] = { 65 }; printf("%c\n", c[0]); return 0;}从上面的程序我们可以分析出,其实字符数组的定义里面,不一定只能写字符,也可以写数字,代表acsii值为…的数,...原创 2019-07-11 21:29:10 · 398 阅读 · 0 评论 -
25、数组的本质
1原创 2019-07-07 10:05:10 · 360 阅读 · 0 评论 -
29、字符串典型问题分析
1原创 2019-07-09 21:21:56 · 188 阅读 · 1 评论 -
28、C语言中的字符串
1原创 2019-07-09 17:20:38 · 280 阅读 · 0 评论 -
27、指针和数组分析(下)
1原创 2019-07-09 10:31:06 · 104 阅读 · 0 评论 -
36、指针阅读技巧分析
1、笔试中的问题下面的标识符代表什么含义?1、 int (*p1)(int*, int (*f)(int*));2、 int (*p2[5])(int*);3、 int (*(*p3)[5])(int*);4、 int*(*(*p4)(int*))(int*);5、 int (*(*p5)(int*))[5];右左法则:— 从最里层的圆括号中未定义的标识符看起— 首先往右看,...原创 2019-08-08 22:16:15 · 138 阅读 · 0 评论 -
37、动态内存分配
1、动态内存分配的意义C语言中的一切操作都是基于内存的变量和数组都是内存的别名— 内存分配由编译器在编译期间决定— 定义数组的时候必须指定数组长度— 数组长度是在编译期就必须确定的需求:程序运行过程中,可能需要使用一些额外的内存空间2、malloc和freemalloc和free用于执行动态内存分配和释放malloc所分配的是一块连续的内存malloc以字节为单位...原创 2019-08-08 22:45:58 · 108 阅读 · 0 评论 -
47、递归函数分析
1、递归函数函数体内部可以调用自己递归函数— 函数体中存在自我调用的函数递归函数是递归的数学思想在程序设计中的应用— 递归函数必须有递归出口— 函数的无限递归将导致程序栈溢出而崩溃2、递归函数设计示例一用递归的方法编写函数求字符串长度#include <stdio.h>#include <malloc.h>int strlen(const c...原创 2019-08-11 19:50:57 · 560 阅读 · 0 评论 -
46、函数与宏分析
1、函数与宏宏是由预处理器直接替换展开的,编译器不知道宏的存在函数是由编译器直接编译的实体,调用行为由编译器决定多次使用宏会导致最终可执行程序的体积增大函数是跳转执行的,内存中只有一份函数体存在宏的效率比函数高,因为是直接展开的,无调用开销函数调用会创建活动记录,效率不如宏程序:指针指向的内存区域清零#include <stdio.h>#define RESET...原创 2019-08-11 12:16:50 · 161 阅读 · 0 评论 -
45、函数参数的秘密(下)
1、调用约定调用约定是预定义的可理解为调用协议调用约定通常用于库调用和库开发的时候2、可变参数C语言可以定义参数可变的函数参数可变函数的实现依赖于stdarg.h头文件— va_list — 参数集合— va_arg — 取具体参数值— va_start — 标识参数访问的开始— va_end — 标识参数访问的结束#include <stdio.h>#...原创 2019-08-11 11:19:04 · 101 阅读 · 0 评论 -
44、函数参数的秘密(上)
1、原创 2019-08-10 20:43:02 · 118 阅读 · 0 评论 -
43、函数的意义
1、声明和定义声明的意义在于告诉编译器程序单元的存在定义则明确指示程序单元的意义C语言通过extern 进行程序单元的声明一些程序单元在声明时可以省略extern1.c#include <stdio.h>#include <malloc.h>extern int g_var; //声明不分配空间,定义才分配空间extern stru...原创 2019-08-10 20:40:40 · 131 阅读 · 0 评论 -
42、内存操作经典问题分析2
1、常见的内存错误结构体成员指针未初始化结构体成员指针未分配足够的内存内存分配成功,但并未初始化内存操作越界2、内存操作的交通规则动态内存申请之后,应该立即检查指针值是否为NULL,防止使用NULL指针 int* p = (int*)malloc(56); if (p != NULL) { //Do something here! } free(p);当你f...原创 2019-08-10 17:24:07 · 104 阅读 · 0 评论 -
41、关于string的一些问题及概述
1、strcat —— 字符串连接strcat(字符数组1,字符数组2)注意:字符数组1必须足够大,可以满足两个连接在一起的内存。2、strcpy 函数—— 字符串复制函数strcpy(字符数组或动态内存,字符串)strcpy的第一个参数,必须指向一个可用的内存,可以是字符数组,也可以是malloc一段内存,但是不能是字符串,因为字符串是常量,不能改变。3、strcmp 函...原创 2019-08-09 22:40:01 · 152 阅读 · 1 评论 -
40、内存操作经典问题分析1
1、野指针指针变量中的值是非法的内存地址,进而形成野指针野指针不是NULL指针,是指不可用内存地址的指针NULL指针并无危害,很好判断,也很好调试C语言无法判断一个指针所保存的地址是否合法2、野指针的由来局部指针变量没有被初始化指针所指向的变量在指针之前被销毁使用已经释放过的指针进行了错误的指针运算进行了错误的强制类型转换#include <stdio.h>...原创 2019-08-09 22:10:49 · 121 阅读 · 0 评论 -
39、程序的内存布局
1、程序文件的一般布局不同代码在可执行程序中的对应关系从上面图中,我们可以发现初始化了的全局变量和静态局部变量映射到.date段;没有初始化了的全局变量和静态局部变量映射到.bss段;函数映射到.text段。所以.date段、.bss段对应程序的静态存储区2、程序和进程程序和进程不同— 程序是静态的概念,表现形式为一个可执行程序— 进程是动态的概念,程序由操作系统加载运行后得到...原创 2019-08-09 16:19:09 · 109 阅读 · 0 评论 -
38、程序中的三国天下
1、程序中的栈栈是现代计算机程序里最为重要的概念之一栈在程序中用于维护函数调用上下文函数中的参数和局部变量存储在栈上栈:就是后进先出的行为栈保存了一个函数调用所需的维护信息— 参数— 返回地址— 局部变量— 调用上下文— …函数调用时,对应的栈空间在函数返回前是专用的函数调用结束后,栈空间被释放,数据不再有效#include <stdio.h>#in...原创 2019-08-09 12:19:44 · 112 阅读 · 0 评论 -
26、指针和数组分析(上)
1、数组的本质数组是一段连续的内存空间数组空间大小为sizeof(a)数组名可以看做指向数组第一个元素的常量指针提出问题:— 假设a是一个数组,a+1 = ?— 假设a是一个指针,a+1 = ?— 指针运算的意义是什么?结果又是什么?...原创 2019-07-09 10:28:46 · 141 阅读 · 0 评论 -
24、指针的本质
变量代表一段内存的别名,但并不是只能通过变量才能访问一段内存了,指针也可以1、 号的意义*在指针声明时,* 号表示所声明的变量为指针在指针使用时,* 号表示取指针所指向的内存空间中的值指针 p 里面存放的是变量 i 的地址,*p 表示取变量 i 的值。p = &i;*p = i;为什么指针的大小占用为4个字节?因为如果系统是32位,地址寻址范围为4个字节,所有的3...原创 2019-06-27 11:57:24 · 284 阅读 · 0 评论 -
17、三目运算符和逗号表达式
1、三目运算符a ? b : c //a为真,返回b;a为假,返回c注:三目运算符不能作为左值使用,三目运算符最终返回的是一个值,而不是一个变量,如果作为左值使用,那就是两个常数相互赋值,明显错误。因此三目运算符可以作为右值使用。#include <stdio.h>int main(){ int a = 1; int b = 2; int c = 0; ...原创 2019-06-24 17:53:07 · 242 阅读 · 0 评论 -
4、浮点数的秘密
1、浮点数在内存中的存储方式:符号位,指数位,尾数float 在内存中占4个字节,double 在内存中占8个字节。浮点数的存储是依照IEEE754标准,指数位用移码表示,尾数用原码表示,且省略1。所以float尾数位为24,double尾数位为64。对float: 指数为移码 = 011111111+偏移量对double:指数为移码 = 01111111111+偏移量例题:实数8.2...原创 2019-06-17 21:27:51 · 709 阅读 · 0 评论 -
19、宏定义使用分析
宏开始给我的两个印象:1、可以用来定义常量 2、定义代码块1、C语言中的宏定义— #define 是预处理器处理的单元实体之一— #define 定义的宏可以出现在程序的任意位置— #define 定义之后的代码都可以使用这个宏2、定义宏常量— #define 定义的宏常量可以直接使用— #define 定义的宏常量本质为字面量#include <stdio.h>#...原创 2019-06-25 13:58:30 · 217 阅读 · 0 评论 -
3、有符号数和无符号数
有符号和无符号://不写unsigned默认为有符号的整型,只有整数类型(比如char,short,int,long)才能声明unsigned变量。一个字节能表示的最大的无符号数为:2^8-1=256-1=255 0~255一个字节能表示的最大的有符号数为:2^7-1=128-1=127 -128~127最高位为1,表明这个数为负数最高位为0,表明这个数为正数在计算机内部,用原码...原创 2019-06-17 16:11:25 · 3876 阅读 · 5 评论 -
1、结构体、柔型数组以及union
结构体:用户自己建立不同数据类型组成的组合型的数据结构。struct student {成员列表};struct student student1;// struct为声明结构体类型的关键字,student为结构体名// struct student 为一个结构体类型// student1为struct student 类型的变量或者在定义结构体类型的同时定义结构体变量:...原创 2019-06-17 15:15:08 · 520 阅读 · 0 评论 -
18、编译过程简介
编译器—— 预处理器 → file.i(中间代码)—— 编译器 → file.s(汇编文件)—— 汇编器 → file.o (二进制文件)—— 链接器♦ 预编译— 处理所有的注释,以空格代替— 将所有的 #define 删除,并且展开所有的宏定义— 处理条件编译指令 #if,#ifdef,#elif,#else,#endif— 处理 #include ,展开被包含的文件— ...原创 2019-06-25 10:57:22 · 83 阅读 · 0 评论 -
2、基本类型
数据类型:固定内存大小的别名,用来定义变量。例如:int i sizeof(i) = sizeof(int) = 4变量:一段连续存储空间的别名。变量的内存大小取决于定义它的数据类型。sizeof :返回类型或对象占的字节大小。typedef :自定义数据类型。例如typedef int INT32 INT32就是和int相同功能的数据类型...原创 2019-06-17 15:15:46 · 120 阅读 · 0 评论 -
9、const 和 volatile 分析
const分析1、const的分歧const修饰的变量是只读的,本质上还是变量,不是常量。只读的意思在我看来,就是变量只能出现在在赋值符号的右边。const修饰的局部变量依旧存储在栈上,只不过是read only的,(只读的意思在我看来,就是只能在赋值符号的右边。)所以一般的赋值不能改变它的值,但是指针运算可以修改它的值。const修饰的全局变量依旧存储在全局数据区,也就是在全局变量本身呆...原创 2019-06-19 22:06:38 · 233 阅读 · 0 评论 -
8、void 的意义
1、void 修饰函数代表没有参数和没有返回值2、void不是实际的类型,而是一种抽象的类型。不能用void定义变量,但是可以用void 定义指针。比如:void a; //errorvoid p[5]; //error void *p; //正确可以定义void 类型的指针,因为指针都是固定4Byte(win32)...原创 2019-06-19 20:34:04 · 1842 阅读 · 0 评论 -
7、各种语句
两种分支语句1、 if…else 语句注意的点:(1)else不独立存在,总与它最近的 if 相匹配(2)变量与0比较,0应该出现在比较符号左边。(3)float型变量不能直接进行0值比较,需要定义精度2、switch…case语句(单值多分支)语法规则:switch (expression) { //别忘记大括号 case CONS...原创 2019-06-19 19:49:22 · 135 阅读 · 0 评论 -
20、条件编译
条件编译就是宏定义加上预处理的应用,作用在于同一份代码产生不同的产品1、基本概念— 条件编译的行为类似于C语言的 if…else…— 条件编译是预编译指示命令,用于控制是否编译某段代码#include <stdio.h>#define C 1int main(){ const char* s; #if(C == 1) s = "This is first pri...原创 2019-06-25 17:54:02 · 280 阅读 · 0 评论 -
5、类型转换
1、强制类型转换#include <stdio.h>int main(){ long l = 800; int i = (int) l; return 0;} 目标类型能够容纳目标值,结果不变。目标类型不能容纳目标值,产生截断。2、隐式类型转换(只传值,类型不发生改变)char c = 'a';int i = c; //c还是char类型,只是把值传给...原创 2019-06-17 22:39:18 · 111 阅读 · 0 评论 -
16、++、- - 操作符的本质
1、一个头疼的问题#include <stdio.h>int main(){ int i = 0; int r = 0; r= (i++) + (i++) + (i++); printf("i = %d\n", i); printf("r = %d\n", r); r = (++i) + (++i) + (++i); printf("i = %d\n", i)...原创 2019-06-24 16:55:05 · 176 阅读 · 0 评论 -
23、# 和 ## 操作符使用分析
1、# 运算符#运算符用于在预处理期将宏参数转换为字符串#的转换作用是在预处理期完成的,因此只在宏定义中有效编译器不知道# 的转换作用用法 : #define STRING(x) #x printf(“%s\n”,STRING(Hello World !));#include <stdio.h>#define STRING(x) #xint main(){...原创 2019-06-27 10:25:38 · 157 阅读 · 0 评论 -
15、位运算符分析
C语言中的位运算符位运算符直接对 bit 位进行操作,其效率最高。(1)左移、右移运算符注意点—— 左操作数必须为整数类型char、short是左操作数的类型时, 会被隐式转换成 int 后进行移位操作—— 右操作数的范围必须为 [0,31]—— 左移运算符 << 将运算数的二进制位左移规则:高位丢弃,低位补0—— 右移运算符 >> 将运算数的二进制位右移...原创 2019-06-24 15:05:20 · 579 阅读 · 0 评论