第一次写博客,决定把自己写的课程笔记全部上传一下,方便后来人学习~ o(* ̄▽ ̄*)o
从自学转码上岸到现在快两年了,收集了很多语言和编程思路方面的重难点,供参考
参考资料:
程序设计入门—C语言 - 网易云课堂 (163.com)
目录
如何计算这些数据(表达方式,自然语言→流程图/程序框图→程序语言)
·要产生一组元素组合,用各组合单元写一个多重循环(注意兼顾排序和筛选)
②判断质数/合数,a%(2到n-1)!= 0恒成立为质数,否则为合数
③求最大公约数gcd(a,b)/最小公倍数lcm(a,b),a x b = gcd(a, b) x lcm(a,b)
④斐波那契数列(兔子繁衍问题):f(n)=f(n-1)+f(n-2)(n>2) f(0)=1;f(1)=1;
⑤整数划分:把一个正整数n表示成一系列正整数之和,最大加数不超过m,求划分总数
⑥杨辉三角:两条斜边都是由数字1组成的,而其余数字则等于它肩上的两数之和
⑧判断闰年,年份是4的倍数且不是100的倍数,或者是400的倍数
1、c标准库:C 运行时库参考 | Microsoft Learn
函数free(申请到的空间的首地址):动态内存分配释放空间。
可变数组:元素总数可增长,当前大小可知,元素可以访问的数组。
三、IDE(集成开发环境,Integrated Development Environment)
需要得到什么数据,程序里面设置什么变量,
怎么用来表达这些数据,怎么读入这些数据
如何计算这些数据(表达方式,自然语言→流程图/程序框图→程序语言)
(开头定义临时变量,然后输入临时变量,再对临时变量进行处理,最后执行输出操作)
·利用中间变量做交换
·计算前先存储初始值以备用
·要产生一组元素组合,用各组合单元写一个多重循环(注意兼顾排序和筛选)
·初始化变量:
①求和程序,结果变量初始化为0;求积程序,结果变量初始化为1
②需要反复进行的初始化,写在循环体中,不要写在程序开头的定义/for循环的括号里
·无效化语句:
①删除②转注释
·使用标志:
①作为条件测试(切换状态),isPrime=1/0
②正负号转换(相反数),sign=1,sign=-sign
·检验:
①电脑进行调试,注意测试各种边界数据和特殊数据
②人脑进行模拟,在纸上模拟程序的运行,写出变量的变化(变量表格法)
(若要模拟大次数循环,可以模拟小次数循环并推断)
③交互式输出,在程序适当的地方表明程序运行到哪里,或者输出变量的内容
(常常在输入后马上把该输入输出,检验输入是否读入和是否读对)
·数字处理:
(逆序输出,循环%10并输出;正序输出,
先计算数位,后循环整数相除取第一位输出/先逆序,后逆序输出)
整数相除结果是整数,商不保留小数部分;
一旦除数和被除数中有一个是浮点数,那么结果也是浮点数,并且是 double 类型的浮点数。
将double/float强制转换为int,不保留小数部分。输出%.xf,四舍五入。
函数floor(x):向下取整,函数ceil(x):向上取整。
②判断质数/合数,a%(2到n-1)!= 0恒成立为质数,否则为合数
(注意a=1的特殊情况;一个数的因数必然小于等于这个数的平方根,即a%(2到根号n)!= 0)
③求最大公约数gcd(a,b)/最小公倍数lcm(a,b),a x b = gcd(a, b) x lcm(a,b)
https://zhuanlan.zhihu.com/p/77669220
- 分解质因数法(通用,可求三个数字及以上)
最大公约数为公有质因数之积;最小公倍数为公有质因数和各自独有质因数之积。
- 短除法(通用,可求三个数字及以上)
最大公约数为左侧因数之积;最小公倍数为左侧因数和下侧商之积。
- 更相减损术(九章算术;a=b时,最大公约数为相等值,最小公倍数=a x b/ gcd(a, b))
- 辗转相除法(欧几里得算法;余数为0时,最大公约数为a,最小公倍数=a x b/ gcd(a, b))
④斐波那契数列(兔子繁衍问题):f(n)=f(n-1)+f(n-2)(n>2) f(0)=1;f(1)=1;
斐波那契数列的三种解法及时间复杂度_dangzhangjing97的博客-CSDN博客
斐波那契数的时间复杂度、空间复杂度详解_lxf_style的博客-CSDN博客
- 递归算法:T(n)=O(2^(n-1)-1)=O(2^n),S(n)=O((n-1)C)=O(n)
- 尾递归算法:T(n)=O(n-2)=O(n),S(n)=O(n-2)=O(n)
- 循环算法:T(n)=O(n-2)=O(n),S(n)=O(3)=O(1)
⑤整数划分:把一个正整数n表示成一系列正整数之和,最大加数不超过m,求划分总数
【算法】整数划分问题_将正整数 n 表示成一系列正整数之和,称之为一个划分
⑥杨辉三角:两条斜边都是由数字1组成的,而其余数字则等于它肩上的两数之和
【C语言】-杨辉三角_杨辉三角c语言程序_学Java的冬瓜的博客-CSDN博客
https://www.zhihu.com/question/20993504/answer/16946150
1、k进制转10进制:位值原理展开
2、10进制转k进制:
整数部分除k取余法(商为0时,余数倒写),
小数部分乘k取整法(整数顺写,直到积为0/精度达到要求)
3、k进制转k进制:
法1:k进制→10进制→k进制
法2:2进制和8进制互转,3位一组;2进制和16进制互转,4位一组
⑧判断闰年,年份是4的倍数且不是100的倍数,或者是400的倍数
’a’=97>’A’=65,’a’-’A’=两字符在ascii表中的距离=32
1、大写字母→小写字母:a+(’a’-’A’)=a+’a’-’A’
2、小写字母→大写字母:a-(’a’-’A’)=a+’A’-’a’
- 首先求总行数,作为重要的控制参数
- 找规律,观察行数与每行符号/空格数关系
- 若上下对称则分成上下两半,多重循环遍历行数,遍历每行的符号/空格数
步骤:遍历,判断是否相等
计算次数:n(n为数据总数)
前提:数据有序
步骤:当left<=right,求mid、做判断、移动区间。。。
计算次数:log2n(n为数据总数)
各种排序算法时间复杂度 - 枫飞飞 - 博客园 (cnblogs.com)
步骤:遍历,当元素小于前驱、在之前的部分倒着遍历将比其大的元素往后搬、插入元素。。。
计算次数:直接/折半插入排序n2,希尔排序n1.3(n为数据总数)
步骤:遍历,两两比较相邻元素、若出现逆序则交换a[j]和a[j-1]。。。
(倒着遍历,两两比较相邻元素、若出现逆序则交换a[j]和a[j-1]。。。)
计算次数:n2(n为数据总数)
步骤:取第一个元素作为枢轴进行划分。。。
计算次数:nlog2n(n为数据总数)
步骤:遍历,求minid、交换a[minid]和a[i]。。。
(倒着遍历,求maxid、交换a[maxid]和a[len-1]。。。)
计算次数:n2(n为数据总数)
步骤:
S1建堆:自底向上,将待排序序列小/大元素不断下坠;
若破坏下一级堆,继续采用上述方法构造下一级堆。。。
S2排序:堆顶元素与堆底元素互换;自底向上,将待排序序列小/大元素不断下坠。。。
计算次数:nlog2n(n为数据总数)
步骤:当left<right,求mid、对左右半部分递归地进行归并排序、将左右半部分归并成一个。。。
计算次数:nlog2n(n为数据总数)
步骤:初始化r个空队列,按关键字位权重递增/减次序,对d个关键字位进行分配和收集
计算次数:d(n+r)(n为数据总数)
编程格式:
·变量避免一专多能
·输出尽量单一出口
·能初始化尽量初始化,往往能够简化程序
·c不关心空格/换行
·用英文全角
·*不能省略;==错用成=;输入端不能决定浮点数精度,只能输出端决定
·编程字体0:与O区别
常见输出格式问题:
有无空格,有无换行,中英文全半角标点符号,浮点数精度
(全部输出最后的换行符,一般会自动处理掉)
编程错误:
·segmentation fault:
①数组越界:检验是否越界并跳出/用变量表示元素总数
·定义字符数组,字符总数至少为 需要写入的字符数+1(包括最后的0)
②指针错误:没加&
·定义指针变量后,需要进行初始化,赋予实际变量的地址,指向安全的地方,再开始使用
定义指针却进行写入,应该对指针进行初始化,指向安全的地址,才能进行写入
定义字符指针却进行写入,应该定义字符数组/对字符指针进行初始化,指向安全的地址
·箭头运算符->左边的指针必须确保不是NULL,如链表的首节点为空
编译 f9
运行 f10
编译运行 f11
调试 f5(常配合断点设置)
停止输出 ctrl+c
EOF ctrl+z(windows)/ctrl+d(unix/linux)
缩进 tab
撤销缩进 shift+tab
切换注释状态 ctrl+/
·切换目录:
S1访问其他盘 盘符:
S2进入具体文件夹 cd 下层文件夹/剩余路径
S3返回上层目录 cd..
·显示指定的目录/文件的详细信息 dir 目录/文件
·显示指定的目录/文件的详细信息 ls 目录/文件(仅linux可用)
·查看指定的文件的内容 more 文件1 文件2
·查看特殊格式的指定文件内容 od 文件1 文件2(仅linux可用)
·查看文件末尾若干行代码 tail -n 行数 文件(仅linux可用;若省略红字,则为少数几行)
·文件输入/输出:
①重定向 .\文件 < a.in / > a.out
②定义FILE类型指针
FILE* fp=fopen(“文件”,“模式”);
if (fp) {
fscanf(fp,“格式控制字符串”,&输入参数一,&输入参数二);
fclose(fp,“格式控制字符串”,&输出参数一,&输出参数二);
} else {
...
}
·输出指定的文件的内容 cat 文件1 文件2(仅linux可用)
·编辑指定的文件的内容 vi 文件1 文件2(仅linux可用)
·执行文件 .\文件
·删除文件 在windows中,rmdir 文件;在linux中,rm 文件
1、命名:
①只能包含字母、数字、下划线;只能以字母/下划线打头,不能以数字打头
②不能包含空格,空格用下划线表示
③不使用关键字和函数名
④简短而具有描述性,
⑤
2、分类:
①关键字②预定义标识符(包括函数名和预处理命令名)
③用户标识符(不能使用关键字,可以使用预处理命令名)
#include <stdio.h>
int main(int argc,char const *argv[])
{
(缩进)要执行的命令;
(缩进)return 0;
}
(注意缩进不要错)
/
void main()
{
(缩进)要执行的命令;
}
(注意缩进不要错)
数据类型 A,B
(c99可以在任何地方定义变量,ansi c只能在代码开头定义变量;
若不进行初始化,变量的默认值为内存位置原有的值)
const 数据类型 A,B = 默认值1,默认值2
(定义常量,有利于理解常量内容,并且方便统一修改;一般在代码开头定义常量;
定义常量的同时必须初始化,一经初始化就不能再修改;命名全大写;
常量分为直接常量和符号常量,直接常量/字面量是直接写在程序里的常量)
A=B,C=D
数据类型 A=B,C=D
(给多个变量赋值时,必须单独给每个变量赋值,不能把一个值赋给多个变量;
避免嵌入式赋值,容易出错且可读性差;定义变量/常量时的赋值又叫初始化)
C语言中scanf与printf的区别_c++ printf和scanf区别-CSDN博客
①通过参数,进行格式化输出
printf(“格式控制字符串”,输出参数一,输出参数二)
(返回正确输出字符的个数,当没有输出/输出字符有错,返回特殊值EOF(-1);
读到0/’\0’/NULL为止)
②获取格式化输入,存储进参数
scanf(“格式控制字符串”,&输入参数一,&输入参数二)
(返回正确读入参数的个数,当没有输入/输入参数有错,返回特殊值EOF(-1)
输入参数的默认值为0;读到空白为止;读入字符串时,
- 每一个字符都会存在缓冲区内,包括最后的空白
- 两次读入字符的scanf()中间要加入一个getchar()来刷新缓冲区)
(最优的清除输入缓冲区的方法,while ((ch=getchar())!='\n'&&ch!=EOF) ;
【C语言】getchar 函数的正确使用_getchar()函数具体应该怎么使用-CSDN博客)
举例:
1、printf(“%d”,数字);
2、printf(“y=f(%f)=%.2f\n”,x,y);
%f保留的是6位小数,而%.2f则指定输出的时候保留2位小数。
(float最多保留6位有效数字,double最多保留12位有效数字)
3、printf("%4d/%04d",D[i]);
%4d/%04d表示在输出一个小于4位的数值时, 将在前面补空格/0使其总宽度为4位。
4、printf(“字符串”);
5、printf(“%.2s”,字符数组/指针);
%.2s 表示在输出该字符串时,最多只能输出2个字符。
6、printf("%4s",字符数组/指针);
%4s表示在输出一个小于4位的字符串时, 将在前面补空格使其总宽度为4位。
7、scanf(“%7s”,字符数组/指针);
%7s 表示在输入该字符串时,最多只能读入7个字符,一般为(字符数组大小-1)。
8、
9、
同理,连续两个”\”,会输出”\”
11、[]的使用,输入字符串并以空白外的其它字符为定界符时使用,
将匹配所有在结果字符集中出现的字符,遇到非结果字符集中的字符时输入就结束
(只读[]之间的字符)
①若没有^,在[]之间的字符是结果字符集,不在[]中的可输入字符都作为定界符
(读到[]之间的字符就停止)
②若有^,其余可输入字符是结果字符集,在^和]之间的字符是定界符
--------格式控制说明---------------------------------------------------------
%d 十进制有符号整数(输出时自动将八/十六进制转换为十进制)
%i 十进制有符号整数(输入、输出时自动将八/十六进制转换为十进制)
%u 十进制无符号整数
%o 八进制无符号整数(输入时可带也可不带前缀0,输出时不带前缀0)
%x, %X 十六进制无符号整数(输入时可带也可不带前缀0x,输出时不带前缀0x)
%hd 有符号短整型
%hu 无符号短整型
%ld 有符号长整型
%lu 无符号长整型
%lld 有符号超长整型
%llu 无符号超长整型
%f 小数形式有符号单精度浮点数(输入、输出float,或输出double时用)
%lf 小数形式有符号双精度浮点数(输入double时用)
%e,%E 指数形式有符号单精度浮点数(输入float,或输出float/double时用)
%le,%lE 指数形式有符号双精度浮点数(输入double时用)
%a,%A 十六进制浮点数形式有符号双精度浮点数(输入、输出double时用,仅c99可用)
%c 单个字符
%s 字符串(输入时读到空白为止,输出时读到0/’\0’/NULL为止)
%[] 所允许的字符(输入字符串并以空白外的其它字符为定界符时用)
%p 指针的值(一般用十六进制表示,不包括前缀0x)
%g,%G 自动选择合适的表示法(输出时使输出宽度更短)
%n 已经正确输入/输出字符的个数,将其填到给出的指针当中
------常用转义字符-----------------------------------------------------------
\b 退格(BS)(光标回退一格,输入的新字符从光标处开始覆盖)
\n 换行(LF)(回车+换行,重新从左边开始并到下一行处)
\f 换页(FF)
\r 回车(CR)(重新从左边开始,输入的新字符从左边开始覆盖)
\t 制表符(HT)(到下一个制表位处;制表位是每行的固定位置,不是固定的字符数量)
\ooo 八进制数对应的字符,其中ooo是1-3位八进制数
\xhh 十六进制数对应的字符,其中hh是1-2位十六进制数
函数:带名字的代码块,函数(信息)。命名描述性,只使用小写字母和下划线。(储存大量代码,用于多次执行同一任务;注意每个函数应只负责一项具体的工作,避免同一函数执行的任务太多;多个函数嵌套/串接使用)
重构:将代码大部分逻辑划分到一/多个负责具体工作的函数,使其清晰、易于维护和扩展。
定义函数:
返回类型 函数名(参数表)
{
(缩进)函数体;
}
(注意缩进不要错,圆括号不要漏;没有返回值的函数,返回类型为void,
函数体中,可不写return语句/写return语句但省略值;
c中函数不能嵌套定义,但可以在一个函数定义中放其他函数的原型;
写在调用它的函数的后面。)
函数原型(声明函数):
函数头;
(注意冒号不要漏;说明返回类型、函数名、参数的类型和数量,可省略参数名称;
函数原型中,没有参数圆括号内写void,空着表示参数表未知;写在调用它的函数的前面。)
声明外部函数:
extern 函数头;
(在需要使用的源文件内声明,想引用哪个函数就声明哪个函数;
extern的引用方式比包含头文件要简洁,还可以加速预处理过程节省时间;
注意冒号不要漏;说明返回类型、函数名、参数的类型和数量,可省略参数名称;
函数原型中,没有参数圆括号内写void,空着表示参数表未知;写在调用它的函数的前面。)
函数调用:
·特点:最后被调用的函数最先执行结束(LIFO)
·函数调用栈存储内容:①函数调用返回地址②实参③局部变量
形参(parameter):函数定义时使用的参数。
实参(argument):函数调用时使用的参数。
特殊形参:
①*元组(传递任意数量位置实参;在函数体内使用时不需要*;
创建空元组,并将收到的所有实参都封装到该元组中)
②**字典
(传递任意数量关键字实参;在函数体内使用时不需要**;
创建空字典,并将收到的所有关键字实参都封装到该字典中)
位置实参:
返回类型 函数名(数据类型 名称1,数据类型 名称2)。。。
函数(值1,值2)
函数参数:
·传递方式: C语言中函数参数传递的三种方式_CSDN博客_函数参数传递的三种方式
①值传递(修改了复制的新内存的值)
②地址传递(修改了地址所指向的原内存的值)
③引用传递(仅cpp可用,同地址传递)
全局变量:定义在块外的变量,生存期/作用域是整个程序。
局部变量:定义在块内的变量,生存期/作用域是是块内。
静态全局变量:定义在块外的变量,定义时前加static修饰,
生存期/作用域是定义所在的文件。
静态局部变量:定义在块内的变量,定义时前加static修饰,
生存期是整个程序,作用域是块内。
外部函数:定义时前加extern修饰,若省略则默认为外部函数,
生存期/作用域是定义所在的文件,但可以通过声明扩展到其他文件。
静态函数:定义时前加static修饰,
生存期/作用域是定义所在的文件。
(块:{}之间,生存期:变量生存的时间,作用域:变量作用的范围;Tips:
①局部变量和全局变量同名时,优先使用局部变量(就近原则),但是同一个块内不能定义同名变量;②全局变量、全局指针、静态全局变量、静态局部变量若不做初始化,会被默认初始化为0/NULL,局部变量不会被默认初始化;③全局变量只能用已知常量做初始化,局部变量可以用任意表达式做初始化;④当一个源程序由多个源文件组成时,全局变量、函数在各个源文件中均有效,而静态全局变量、静态函数只在其定义所在的源文件内有效;⑤静态局部变量的初始化只会在首次进入函数时做,下次进入函数时不执行,保持上次离开时的值;⑥若函数返回指针,返回局部变量的地址是危险的,返回传入的地址/全局变量或静态局部变量的地址/动态内存分配的地址是安全的;⑦一般使用局部变量,尽量避免使用全局变量、静态全局变量、静态局部变量,函数内使用会导致该函数不可重入且多线程不安全)
定义全局变量:
数据类型 A,B
(若要在块外调用变量/在块内修改全局变量的值
(不包括修改全局变量元素的值),就要在块外定义全局变量;
c99可以在任何地方定义变量,ansi c只能在代码开头定义变量;
若不进行初始化,变量的默认值为内存位置原有的值)
声明全局变量:
extern 数据类型 A,B
(若要调用在该函数之后定义的变量/在不同源文件间共享变量,
则将变量在块之后/其他源文件内定义,在需要使用的块/源文件内声明;
声明命令行的位置不同会影响变量的作用域;
变量声明时数据类型可以省略;变量声明时不能做初始化,只有定义时可以做初始化)
return语句:——用于函数体中,
将任意函数体中处理过的值返回到调用函数的代码行,同时停止函数的执行
处理值;
return 值;
定义宏:
①不带参数的宏:
#define 宏 值
②带参数的宏:宏、参数均无需说明数据类型
(注意结尾没有分号,因为不是语句;宏的名字只能是一个单词,宏的值可以是任意东西;
定义带参数的宏,整个值要加括号,参数出现的每个地方也都要加括号;若宏的值为多行,最后一行前的每行末尾都要加\;宏定义末尾可以加注释,不影响宏的值;用于做条件编译时,常省略宏的值,通过检查宏是否被定义,来判断该编译哪个部分的代码)
宏优点:1代码复用性2以代码长度增加,换取运行效率提高
宏缺点:1不可调试(预编译阶段进行了替换)2无类型安全检查3可读性差,容易出错
编译前还会进行预处理,做单纯的文本替换,将宏替换为值。
头文件:扩展名为.h的文件,一般包含所有对外公开的全局变量声明,函数原型,宏定义等声明,也可以包含常量定义,枚举/数组/结构/联合定义,类型定义等定义,若包含定义则需要使用标准头文件结构,结合使用宏和条件编译,避免重复定义。
全局变量定义,函数定义
通过编译预处理指令 #include 来引用,做单纯的文本插入,包括系统头文件和用户头文件。
①引用系统头文件:
#include <文件>(在编译器的类库目录中查找)
②引用用户头文件:
#include “文件”(在执行文件所在目录中查找,若无再去编译器的类库目录中查找)
注:①编译器的类库目录位置:
通过环境变量/编译器的选项设置或命令行参数,也可以自行指定寻找头文件的目录
②定义和调用函数的源文件,都要引用函数原型所在的头文件,以明确参数的数据类型
静态库:扩展名为.lib(windows)/.a(unix)的文件,仅在编译时使用。
动态/共享库:扩展名为.lib(windows)/.dll(unix)的文件,仅在运行时使用。
1、c标准库:C 运行时库参考 | Microsoft Learn
函数getchar():读入第一个字符,并显示所有字符,返回值为整型(读到换行符为止)
(返回正确读入字符的个数,当没有输入/输入字符有错,返回特殊值EOF(-1);
读入字符串时,
(1)每一个字符都会存在缓冲区内,包括最后的换行符
(2)反复调用getchar()函数时,依次读出缓冲区内每一个字符,包括最后的'\n'
(3)要读取正确则要使用while((ch=getchar())!='\n')消除换行符)
(返回正确输出字符的个数,当没有输出/输出字符有错,返回特殊值EOF(-1))
函数gets(字符数组/常量指针s):将一个字符串读入s中(读到换行符为止)
(每一个字符都会存在缓冲区内,不包括最后的换行符)
(输出时自动将最后的0/’\0’/NULL转换成换行符)
【C语言知识点总结笔记】吃透getchar()函数,超详细解析!!!_getchar()-CSDN博客
方法cin.peek() :在cpp中,一个用于流(如输入流)的成员函数,
用于查看下一个字符而不从输入流中移除它,返回值是一个char类型的字符
对比输入字符/字符串的3种方式:
①scanf(读到空白为止;最后的空白会存入缓冲区)
②getchar(读到换行符为止;最后的换行符会存入缓冲区)
③gets(读到换行符为止;最后的换行符不会存入缓冲区)
getchar()、gets()和scanf()_a Fang的博客-CSDN博客_getchar吃掉回车的原理
函数pow(x, y):乘方,计算以x为底数的y次幂;返回值为双精度浮点数
函数sqrt(x):开平方,计算非负实数x的算数平方根;返回值为双精度浮点数
函数exp(x):求e的幂次方,计算以e为底数的x次幂;返回值为双精度浮点数
函数fabs(x):浮点数绝对值,计算浮点数x的绝对值;返回值为双精度浮点数
函数floor(x):向下取整,数学符号⌊⌋;返回值为双精度浮点数
函数ceil(x):向上取整,数学符号⌈⌉;返回值为双精度浮点数
计算字符串长度(不包括结尾的0),返回值为无符号长整型(读到0/’\0’/NULL为止)
函数strncmp(字符数组/常量指针s1,字符数组/常量指针s2,比较字符数n):
比较两个字符串,返回s1-s2的值(原理分别对每个字符的ascii码做比较,直到出现不相同的字符或遇到’\0’为止;若出现不相同的字符,则以第一个不相同的字符的比较结果为准)
(1)s1==s2:0 (2)s1>s2:正数 (1)s1<s2:负数
函数memcpy(void*目标地址s1,void*源地址s2,复制内容字节总数n):
把s2指向的任意类型对象复制到s1地址的空间,返回void*s1
(原理从s1[0]开始,分别复制每个对象;要求s1地址的空间足够,且两地址的空间不重叠)
函数strncpy(字符数组/普通指针s1,字符数组/常量指针s2,复制字符数n):
把s2指向的字符串(包括结尾的0)复制到s1地址的空间,返回s1
(原理从s1[0]开始,分别复制每个字符;要求s1地址的空间足够,且两地址的空间不重叠)
函数strncat(字符数组/普通指针s1,字符数组/常量指针s2,复制字符数n):
把s2指向的字符串(包括结尾的0)复制到s1指向的字符串后面,返回s1
(原理从s1[strlen(s1)]开始,分别复制每个字符;
要求s1地址的空间足够,且两地址的空间不重叠)
增加函数调用安全性,避免空间不足:
①函数名str后加n,函数参数加n;只比较/复制n个字符
②用s1、s2长度做动态内存分配:
从右边开始,在字符串中找字符首次出现的位置,返回首个指向该字符的指针/NULL
函数strrstr(字符数组/常量指针s1,字符数组/常量指针s2):
从右边开始,在字符串1中找字符串2首次出现的位置,返回首个指向字符串2的指针/NULL
1、寻找第二次出现的位置:从下一个单元开始,再找一次
2、取出首次出现位置之前的内容:把首次出现位置写成0,取出之后再复原
动态内存分配,申请长度为 字节总数 的空间,返回void *类型的指针。
(不会初始化分配的内存;若空间不足申请失败,则返回0/’\0’/NULL)
动态内存分配,申请长度为 单元总数*sizeof(基础类型) 的空间,返回void *类型的指针。
(分配的内存会被初始化为0;若空间不足申请失败,则返回0/’\0’/NULL)
若原空间大小足够,对原空间进行重分配,p位置不变,将其长度改为新字节总数;
若原空间大小不足够,重新申请长度为 新字节总数 的空间,复制并释放原空间;
返回void *类型的指针。(若空间不足重分配失败,则返回0/’\0’/NULL)
函数free(申请到的空间的首地址):动态内存分配释放空间。
(配合指针初始化习惯,free(0/’\0’/NULL)不会执行也不会报错)
注:①malloc和free需要成对出现,需要设计好程序整体架构保证有free的时机
②借一还一,借多次会造成内存泄漏,丢失之前借到的内存并且无法释放;还多次会报错
函数exit(状态码):立即终止程序的执行,不会执行后续任何代码,但会执行清理操作。
可以传递其他整数值来表示不同的退出状态。通常0表示成功,而非零值表示某种错误。
参数为0,程序正常终止,并返回状态码0;参数为1,程序提前退出,并返回状态码1。
函数abort():立即终止程序的执行,不会执行后续任何代码,也不会执行任何清理操作。
程序在退出之前一般会执行一些清理工作,例如释放资源、关闭文件等。
函数rand():返回一个范围在0到RAND_MAX(至少是32767)之间的伪随机整数。
(若没有设置随机数种子,调用rand()函数时自动设计随机数种子为1;
当随机数种子相同,每次产生的随机数也会相同。)
返回一个指定范围内的伪随机整数:求余+加法
若要产生[m,n]范围内的随机数num,
int num=rand()%(n-m+1)+m;
因为,对于任意数,0<=rand()%(n-m+1)<=n-m
因此,0+m<=rand()%(n-m+1)+m<=n-m+m
举例:要产生10-30的伪随机整数,
srand(time(0));
int num = rand() % (21)+10;
函数system(“命令”):执行系统命令,如
C++ 布尔类型(bool)及BOOL和bool的区别_CSDN博客_bool和bool
C++中定义一个函数为bool类型的作用_CSDN博客_c++bool函数怎么用
bool A=1/0(布尔型:bool,只能赋值为1/0,非0的值都会被存储为 1;true为1,false为0;bool型函数,返回类型为布尔型,函数里可以有return true/false;之类的语句)
文件输入/输出:
①重定向 .\文件 < a.in / > a.out
②定义FILE类型指针
FILE* fp=fopen(“文件”,“模式”);
if (fp) {
fscanf(fp,“格式控制字符串”,&输入参数一,&输入参数二);
fclose(fp,“格式控制字符串”,&输出参数一,&输出参数二);
} else {
...
}
①打开和关闭文件
·打开文件:fopen(“文件”,“模式”)
(返回FILE类型指针,若打开失败,则返回NULL)
自动创建文件,将会在执行文件所在目录。
(若要打开二进制文件,在模式后加b;例如’rb’,以只读模式打开二进制文件)
·关闭文件 fclose(fp)
相对文件路径:若在执行文件所在目录的子文件夹中,’子文件夹\文件’
绝对文件路径:可读取任何位置的文件
②输入和输出文件
·对于文本文件:
1、输入:fscanf(fp,“格式控制字符串”,&输入参数一,&输入参数二)
(返回正确读入参数的个数,当没有输入/输入参数有错,返回特殊值EOF(-1);
输入参数的默认值为0;读到空白为止;读入字符串时,
(1)每一个字符都会存在缓冲区内,包括最后的空白
(2)两次读入字符的scanf()中间要加入一个getchar()来刷新缓冲区)
(最优的清除输入缓冲区的方法,while ((ch=getchar())!='\n'&&ch!=EOF) ;
【C语言】getchar 函数的正确使用_getchar()函数具体应该怎么使用-CSDN博客)
2、输出:fprintf(fp,“格式控制字符串”,&输出参数一,&输出参数二)
(返回正确输出字符的个数,当没有输出/输出字符有错,返回特殊值EOF(-1);
读到0/’\0’/NULL为止)
·对于二进制文件:
- 输入:fread(存储数据的内存地址,每个内存所占字节数,内存个数,fp)
(返回正确读入的基本单元数,当没有输入/输入内容有错,返回特殊值EOF(-1);
输入参数的默认值为0;读到空白为止;读入字符串时,
- 每一个字符都会存在缓冲区内,包括最后的空白
(2)两次读入字符的scanf()中间要加入一个getchar()来刷新缓冲区)
(最优的清除输入缓冲区的方法,while ((ch=getchar())!='\n'&&ch!=EOF) ;
【C语言】getchar 函数的正确使用_getchar()函数具体应该怎么使用-CSDN博客)
2、输出:fwrite(存储数据的内存地址,每个内存所占字节数,内存个数,fp)
(返回正确写入的基本单元数,当没有输出/输出内容有错,返回特殊值EOF(-1);
读到0/’\0’/NULL为止)
③在文件中定位
·获取当前所在文件位置:ftell(fp)(返回当前所在文件位置)
·移动当前所在文件位置:fseek(fp,位移,起始位置)(若移动成功,返回0;失败,返回非0)
https://wenku.baidu.com/view/55a04b0e4873f242336c1eb91a37f111f0850d52.html
①基本类型:整数型(整型),浮点数型(实型),字符型
②构造类型:枚举类型,数组类型,结构体类型,共用体类型
③指针类型 ④空类型
指针类型:基础类型 *
获取变量地址,&变量(取地址运算符&)
·指针常量:指针类型常量,p
(本质是常量,定义的同时必须初始化,一经初始化就不能再修改)
·常量指针:指向常量的指针,p
(本质是指针,指向的对象一旦明确,就不能再通过指针修改)
作用:传结构,保护结构值——当对象作为函数参数时,若对象所占字节数比指针大,往往使用常量指针进行传递,传递字节数少的同时避免函数修改外界变量
区分:指针常量和常量指针 - 百度文库 (baidu.com)
1、*前面的是对指向的对象的修饰,*后面的是对指针本身的修饰
2、const读成常量,*读成指针,const在前*在后是常量指针,const在后*在前是指针常量
①const int* p; ②int const* p; 常量指针
③int * const p; 指针常量
④const int * const p;⑤int const * const p; 二者兼具,指向常量的指针常量,
本质是常量,自己定义的同时必须初始化,一经初始化就不能再修改,
同时指向的对象一旦明确,就不能再通过指针修改
·指针变量:用于存放地址的变量,p
(二级指针:指针的指针,用于存放指针地址的变量)
·指针数组:一系列数据类型相同、元素总数定义后不可变、在内存中连续依次排列的指针,数据类型为int *[元素总数],数组名
(本质是数组,可以保存一系列元素的地址,如存储多个字符数组/字符指针的数组;
通常为了明确指示指针数组的结束,会在指针数组的末尾显式放置一个指向NULL的指针)
·数组指针:指向数组的指针,数据类型为int (*)[指向的数组的元素总数],p
(本质是指针,可以保存二维数组每行的地址,又叫行指针)
·函数指针:指向函数的指针,数据类型为int (*)(参数表),pf(本质是指针,
作用1:传函数,将函数名作为函数参数,用同一函数调用不同函数,方便迭代节省修改量;
作用2:结合指针数组,适用于多路分支调用不同函数,方便迭代节省修改量)
定义指针,int *p/int* p(定义二级指针,int **q/int** q;
定义指针数组,int *数组[元素总数]/int* 数组[元素总数];
定义数组指针,int (*p)[指向的数组的元素总数],
初始化指针指向一维数组int (*p)[指向的数组的元素总数]=&a,
访问一维数组第i个元素,(*p)[i],
初始化指针指向二维数组的0行int (*p)[指向的数组的元素总数]=a,
访问二维数组第i行第j列的元素,*(*(p+i)+j);
定义函数指针,函数名还可以被看作指针,f==pf,int (*pf)(参数表),
初始化指针int (*pf)(参数表)=f,调用函数 (*pf)(参数表) <=> f(参数表))
初始化指针,Int *p/int* p = &i,p指向i
访问指针指向的变量,*p(取变量运算符*)
使多个地址的空间不重叠,定义每一个指针
int *restrict p/int* restrict p(类型限定符restrict)
①指针应用场景一:
函数需要返回多个值,则需要通过传入的指针返回某些值,如交换两个变量的值
②指针应用场景二:
函数只返回状态,通过传入的指针返回值
③指针应用场景三:
【C语言】动态内存的分配_诚挚的乔治的博客-CSDN博客_动态内存分配c语言
做动态内存分配,使用系统头文件stdlib.h中函数malloc(size)和free(a)
特点:相邻两次malloc得到的空间是连续的,但是得到的空间会比malloc的更大,因为除了申请你想要的内存空间外,还会申请一片管理这块可用空间的空间用来存放管理信息
好处:①通过申请,可以控制使用空间的大小
②释放后,可以再次利用申请的空间③在堆区申请,不必担心栈区没有这样大的连续空间
动态内存分配,申请长度为 字节总数 的空间,返回void *类型的指针。
(不会初始化分配的内存;若空间不足申请失败,则返回0/’\0’/NULL)
动态内存分配,申请长度为 单元总数*sizeof(基础类型) 的空间,返回void *类型的指针。
(分配的内存会被初始化为0;若空间不足申请失败,则返回0/’\0’/NULL)
若原空间大小足够,对原空间进行重分配,p位置不变,将其长度改为新字节总数;
若原空间大小不足够,重新申请长度为 新字节总数 的空间,复制并释放原空间;
返回void *类型的指针。(若空间不足重分配失败,则返回0/’\0’/NULL)
函数free(申请到的空间的首地址):动态内存分配释放空间。
(配合指针初始化习惯,free(0/’\0’/NULL)不会执行也不会报错)
注:①malloc和free需要成对出现,需要设计好程序整体架构保证有free的时机
②借一还一,借多次会造成内存泄漏,丢失之前借到的内存并且无法释放;还多次会报错
④定义指针变量后,需要进行初始化,赋予实际变量的地址,指向安全的地方,再开始使用
定义指针却进行写入,应该对指针进行初始化,指向安全的地址,才能进行写入
定义字符指针却进行写入,应该定义字符数组/对字符指针进行初始化,指向安全的地址
⑤习惯上定义指针变量后,先初始化为0/’\0’/NULL,防止在没有真正初始化之前使用指针
⑥若函数返回指针,不能返回局部变量的地址,可以返回传入的地址/全局变量或静态局部变量的地址/动态内存分配的地址;在同一个地方malloc和free,除非函数的作用就是分配内存,否则不要在函数中malloc留待外面free,十有八九会忘记/找不到时机free
⑦指针运算:指针可以进行加减相关运算(+/-/+=/-=/++/--)和比较运算,加减相关运算中出现的数字表示单元数,比较运算比较的是地址的大小
int a[n]; int *p = a; → *(p+i) <=> a[i];
Int a[i][j];int *p = a; → ①*(p+i) <=> a[i]; ②*(*(p+i)+j) <=> *(p[i]+j) <=> *(*(p+i)+j)
注:*(p+i)单独使用时表示的是第i行数据,放在表达式中会被转换为第i行数据的首地址
⑧不同类型的指针大小相同,但不能直接互相赋值;相互之间可以强制转换
(void *类型的指针表示指向的变量类型未知;
常用于底层程序直接访问某个内存地址;进行加减相关运算时等同于char *类型;任何类型的指针都可以直接给 void*类型的指针赋值,而不用类型转换)
空类型:void
基本类型:
·整型常量:(默认为基本整型)
①二进制②八进制③十进制④十六进制
①各种进制数的表示方法:A-F分别对应数字10-15
②负数的二进制表示,是其绝对值的补码,求其原码再反码后补码
https://www.cnblogs.com/junsky/archive/2009/08/06/1540727.html
·整型变量:(默认为有符号整型)
①有/无符号整型signed/unsigned(根据整数Z/非负数N)
②短/基本/长整型/超长整型short int/int/long int/long long int(根据占内存大小)
·实型常量:
①小数形式②指数形式(数字xe/E整数y=x*10的y次方,exp{x}=e的x次方)
·实型变量:
①单精度浮点数型float②双精度浮点数型double
加 +;减 -;乘 *;除 /(整数相除结果是整数,商不保留小数部分;
一旦除数和被除数中有一个是浮点数,那么结果也是浮点数,并且是 double 类型的浮点数)
(空格不影响计算;http://c.biancheng.net/view/1771.html)
运算优先级:单目运算>四则运算>关系/比较运算>
逻辑运算>条件运算>赋值运算>逗号运算
分类:①变量②常量③返回值
分类:①单目运算符(只有一个算子的运算符)②双目运算符(有两个算子的运算符)
for循环每个部分放多个计算,
表达式1,表达式2(逗号运算符,;调用函数时,圆括号内的逗号是标点符号,不是运算符)
B赋值给A,数据类型A=B,(赋值运算符=)
把左边的第一个符号移到右边,a += b <=> a = a+b
(复合赋值运算符+=、-=、*=、/=、%=、&=、|=、<<=、>>=;常用于多行字符串)
条件?条件满足时的值:条件不满足时的值(条件运算符?、:)
反向条件,!A(逻辑非运算符!)
检查多个条件,条件测试A &&/|| 条件测试B(逻辑与运算符&&,逻辑或运算符||)
位运算:1、按位运算 2、移位运算
①将两个数转换成二进制后,进行按位的与,a&b(按位与运算符&)
②将两个数转换成二进制后,进行按位的或,a|b(按位与运算符|)
③将一个数转换成二进制后,进行按位取反,~a(按位取反运算符~)
④将两个数转换成二进制后,进行按位异或,a^b(异或运算符^)
异或运算(半加运算):
从个位开始逐位比较,结果同0异1
a⊕b=(¬a∧b)∨(a∧¬b)
运算符:
数学上,XOR、EOR、EX-OR、⊕;编程上,^
运算律(6):
①恒等律:X⊕0=X(0异或任何数=任何数)
②相反律:X⊕1=X取反(1异或任何数=任何数取反)
③归零律:X⊕X=0(任何数异或自己=把自己置0)
④交换律:A⊕B=B⊕A⑤结合律:A⊕(B⊕C)=(A⊕B)⊕C
⑥自反:A⊕B⊕B=A⊕0=A(异或某数偶数次,相当于没有异或)
应用(6):①比较a、b是否相等②将特定位取反③在汇编中将变量置0④交换a、b,且不使用中间变量⑤判断某数出现奇数次/偶数次⑥互换二进制数的奇偶位(分治法)
⑤将一个数转换成二进制后,向左/右移动n位,a<<n/a>>n(左移运算符<<,右移运算符>>)
左移,结果*2,溢出丢弃,缺位补0,可能改变符号;右移,结果/2,
溢出丢弃,缺位正数(首位为0)/无符号补0,负数(首位为1)补1,不能改变符号;
移位的位数不能是负数,这是没有定义的行为;
应用:①输出一个数的二进制:
②控制单片机的特殊功能寄存器:
·用&使某些位为0,用|使某些位为1(多用于控制选项位数为1)
·使用位段,修改成员变量(多用于控制选项位数>1)
检查是否相等,A == B(相等运算符==)
检查是否不等,A != B(不等运算符!=)
比较数值,A >/>=/</<= B(其他关系/比较运算符>、>=、<、<=)
将两个整数相除并返回余数,a % b(求模运算符%)
给算子取正,+a(单目取正运算符+)
给算子取负,-a(单目取负运算符-)
给变量+1,a++/++a <=> a += 1 <=>a = a+1(递增运算符++)
给变量-1,a--/--a <=> a -= 1 <=>a = a-1(递减运算符++)
计算对象所占字节数,sizeof (数据类型)/sizeof (变量)(sizeof运算符)
获取变量地址,&变量(取地址运算符&)
访问地址指向的变量,*p(取变量运算符*)
访问成员变量,①结构/联合变量.成员变量(取成员运算符.)
②指向结构/联合变量的指针->成员变量(箭头运算符->,读作“arrow”/“所指的”)
以0或’\0’结尾的一系列字符构成的字符数组。
(0标记字符串的结束,在内存中占据一个字节,计入字符数组长度,
但不是字符串的一部分,不计入字符串长度;不能用运算符计算字符串)
·字符串常量:
用双引号括起的一系列字符。
(两个相邻的字符串常量会被自动连接起来)
·字符串变量:
定义字符数组/指针:char 字符串[字符总数]/*字符串
访问字符数组/指针元素:字符串[字符索引]
初始化字符数组/指针:①char 字符串[字符总数] /*字符串= “值”
②char 字符串[字符总数] /*字符串={'字符1', '字符2', …, '字符n', 0或'\0'};
(1)注意分号不要漏;若省略元素总数,会自动数;
第二种方式不支持汉字字符,要用二维数组/指针数组读入多个字符串;
字符数组的字符总数为n+1,包括最后的0
(2)判断将字符串定义为字符数组/指针:
1、若定义为字符数组,则存储为局部变量,可读可写
——需要修改字符串
2、若定义为字符指针,则存储为全局变量,
存储位置未知,调用时拷贝到程序中,只读不可写
——①不需要修改字符串②作为函数参数进行处理③做动态内存分配
字符型:char
·字符型常量:
用单引号括起的单个字符/转义字符。
(单个字符:用单引号括起的1个字母(A、a)/数字/字(中、の)/符号(+、空格、引号);转义/逃逸字符:反斜杠开头的若干字符,表达无法打印的控制字符/特殊字符)
·字符型变量:
字符(字符型)/字符对应的ascii码(整数型)。
用自然语言添加说明,说明代码思路,各部分用来做什么和怎么做。
单行注释,//内容(c99独有,ansi c不支持)
多行注释,/*内容*/(c99和ansi c都支持;也可以用于单行注释)
若不给外国人看一般用中文,将编辑器的编码格式改为utf-8;
或在代码第一行加一句注释,说明编码格式,#coding=/:utf-8
编译前还会进行预处理,处理掉注释代码:
一条语句前/中/后的注释 => 等长的空格/一个空格/直接删除
类型转换:不同数据类型间的转换。
分类:①强制转换:大容量→小容量,可能发生精度丢失
(如double转float/int,或不同类型指针互相转换,或int和string互相转换)
②隐式转换:小容量→大容量,可能会多小数
(如int转float/double)
C#基础③——类型转换(int转double、double转int、Convert)-CSDN博客
下列方法适用于c/c++:
C/C++中string和int相互转换的常用方法_string转int-CSDN博客
下列方法仅适用于c#:
- int转string:
①方法.ToString()
要转换的变量.To转换的目标类型——要转换的整数.ToString()
- string转int:
①Convert转换工厂
Convert.To转换的目标类型(要转换的变量)——Convert.ToInt32(要转换的字符串)
②函数int.Parse()(返回值为整数)
转换的目标类型.Parse(要转换的字符串)——int.Parse(要转换的字符串)
③函数int.TryParse()(返回值为布尔值)
转换的目标类型.TryParse(要转换的字符串,out 结果值)
——int.TryParse(要转换的字符串,out 结果值)
区别:①Convert初始类型不限,Parse/TryParse只能转换表示整数的字符串
②Parse返回值转换失败会产生异常,TryParse转换失败不会产生异常只会返回0
C#(int)中Convert、Parse、TryParse的区别_C#教程_脚本之家 (jb51.net)
一系列连续排列的整型常量。
(当需要定义一系列连续排列的整型常量,或替代const int作为数据类型时使用)
定义枚举,enum 枚举 {名字0=值0,...,名字n=值n}
(名字为整型常量,值依次从0到n;若给名字指定初始值,则下个名字的值为上一个+1;
习惯上定义枚举时,最后一个名字加上一个计数量,表示整型常量总数)
数组类型:数组
一系列数据类型相同、元素总数定义后不可变、在内存中连续依次排列的元素。命名复数。
(在C语言中,多维数组的存储顺序,采用行优先原则,是先行后列的顺序存储方式)
(定义二维数组,数据类型 数组[元素行数][元素列数])
访问数组元素,数组[元素索引](第一个数组元素索引是0,元素索引=元素位置-1,
最小元素索引=0,最大元素索引=元素总数-1;不可以用负数来访问倒数元素)
(访问二维数组元素,数组[元素行号][元素列号])(第一个数组元素行/列号是0,行/列号=行/列数-1,最小行/列号=0,最大行/列号=行/列数-1;不可以用负数来访问倒数元素)
初始化数组,数据类型 数组[元素总数]={元素1,元素2,...元素n,};
(注意冒号不要漏;若省略元素总数,会自动数;
若全局数组完全省略元素/局部数组部分省略元素,会初始化为0)
(初始化二维数组,数据类型 [元素行数][元素列数]={元素1,元素2,...元素n,};
(注意冒号不要漏;若省略元素总数,会自动数;
若全局数组完全省略元素/局部数组部分省略元素,会初始化为0))
①计算数组长度,sizeof(a)/sizeof(a[0])
②遍历数组,for循环,i从0到<数组长度,循环体中imax为最大元素索引
(或者反过来,i从数组长度到>0,执行次数一样为元素总数)
③数组作为函数参数时,往往必须用另一个参数来传入数组长度;数组作为形参写a[],作为实参写a;数组长度作为形参/在函数体中不可以用sizeof计算,作为实参可以
易懂的数组作为函数参数(C语言)-CSDN博客_c数组作为函数参数
④用一个两重循环实现二维数组行和列的遍历,交换下标
一系列相关联的变量,构成的复合数据结构。变量是任意对象,数据类型可以不同。
定义结构类型、结构变量:
①上面定义结构类型,下面定义结构变量
struct 结构 {
(缩进)数据类型 成员变量1;
(缩进)数据类型 成员变量2;
};
struct 结构 结构变量1,结构变量2;
②同时定义结构类型和结构变量
struct 结构 {
(缩进)数据类型 成员变量1;
(缩进)数据类型 成员变量2;
} 结构变量1,结构变量2;
(注意分号不要漏;当之后不再需要使用该结构类型时,可省略结构名,只定义结构变量;通常声明为全局结构类型,在块外、在要使用结构的函数之前声明)
访问结构变量,结构变量
访问成员变量,①结构变量.成员变量(取成员运算符.)
②指向结构变量的指针->成员变量(箭头运算符->,读作“arrow”/“所指的”)
初始化结构变量:
struct 结构 结构变量 = {.成员变量1=值1,.成员变量2=值2};
(注意分号不要漏;若省略成员变量,会按位置赋值;
若全局结构完全省略赋值/局部结构部分省略赋值,会初始化为0)
①结构运算,结构变量和成员变量,都可以做赋值、取地址、作为函数参数
·赋值:
结构变量1 =结构变量2;
结构变量= (struct 结构) {.成员变量1=值1,.成员变量2=值2};
·取地址:
取地址运算符&,优先于取成员运算符.
·作为函数参数:
若需要输入一个结构,则需要写一个函数,传入并返回结构的指针/
在函数中创建并返回一个临时结构变量,从而返回实际修改后结构的值
一系列相关联的变量,构成的复合数据联合。变量是任意对象,数据类型可以不同。
定义联合类型、联合变量:
①上面定义联合类型,下面定义联合变量
union 联合 {
(缩进)数据类型 成员变量1;
(缩进)数据类型 成员变量2;
};
union 联合 联合变量1,联合变量2;
②同时定义联合类型和联合变量
union 联合 {
(缩进)数据类型 成员变量1;
(缩进)数据类型 成员变量2;
} 联合变量1,联合变量2;
(注意分号不要漏;当之后不再需要使用该联合类型时,可省略联合名,只定义联合变量;通常声明为全局联合类型,在块外、在要使用联合的函数之前声明)
访问联合变量,联合变量
访问成员变量,①联合变量.成员变量(取成员运算符.)
②指向联合变量的指针->成员变量(箭头运算符->,读作“arrow”/“所指的”)
初始化联合变量:
union 联合 联合变量 = {.成员变量=值};
(注意分号不要漏;只能对第一个成员做初始化;
若全局联合完全省略赋值,会初始化为0)
①联合运算,联合变量和成员变量,都可以做赋值、取地址、作为函数参数
·赋值:
联合变量1 =联合变量2;
联合变量= (union 联合) {.成员变量=值};
·取地址:
取地址运算符&,优先于取成员运算符.
·作为函数参数:
若需要输入一个联合,则需要写一个函数,传入并返回联合的指针/
在函数中创建并返回一个临时联合变量,从而返回实际修改后联合的值
②常用于得到一个数据的具体某个字节
可变数组:元素总数可增长,当前大小可知,元素可以访问的数组。
·优点:①可随机存取②存储密度高
·缺点:①复制需要时间②边角空间无法利用
各结点包括存储数据元素的数据域,和存储下个结点地址的指针域。
·优点:①改变容量方便②不要求大片连续空间
·缺点:①不可随机存取②要耗费一定存储空间存放指针
链表的添加、搜索、删除、清除:
优缺点:
定义位段:
struct 结构 {
(缩进)整型家族类型 成员变量1:所占位数;
(缩进)整型家族类型 成员变量2:所占位数;
} 结构变量1,结构变量2;
(位段的成员变量必须是int/signed int/unsigned int/char的整型家族类型,后面要加上冒号和位数;位的排列顺序与编译器有关,一般从右往左放,不具有可移植性;若总位数溢出一个int的范围,则用多个int表达这个位段)
①自定义已有数据类型的别名:
typedef 已有数据类型 别名;
②自定义新建数据类型的别名:
typedef struct 结构 / union 联合 {
(缩进)数据类型 成员变量1;
(缩进)数据类型 成员变量2;
} 别名;
(注意分号不要漏;因为有了别名,一般省略结构名;
通常声明为全局结构类型,在块外、在要使用结构的函数之前声明)
语句:一段可执行的代码。
若要测试多个条件,执行多个操作,应用多个if语句/if语句结合for循环
①简单的if语句(1个条件,通过时1个操作)
If (条件测试) {
(缩进)要执行的命令;
}
(注意缩进不要错,圆括号不要漏;若省略{},则只会判断是否执行紧挨着的第一条语句,其他语句则无视条件测试执行;当且仅当要执行的语句只有一条时,可以省略{})
②if-else语句(1个条件,通过时1个操作,不通过时另1个操作)
If (条件测试) {
(缩进)要执行的命令;
} else {
(缩进)要执行的命令;
}
(注意缩进不要错,圆括号不要漏;若省略{},则只会判断是否执行紧挨着的第一条语句,其他语句则无视条件测试执行;当且仅当要执行的语句只有一条时,可以省略{})
③if-else if-else语句(多个条件,依次检查直到通过,并跳过余下的条件,只执行1个操作)
(else if否则如果,主要指如果)
if (条件测试) {
(缩进)要执行的命令;
} else if (条件测试) {
(缩进)要执行的命令;
}。。。 else {
(缩进)要执行的命令;
}
(注意缩进不要错,圆括号不要漏;若省略{},则只会判断是否执行紧挨着的第一条语句,其他语句则无视条件测试执行;当且仅当要执行的语句只有一条时,可以省略{})
④if-else if语句(若知道最终测试条件,应用1个else if代码块替代else代码块)
(else if否则如果,主要指如果)
if (条件测试) {
(缩进)要执行的命令;
} else if (条件测试) {
(缩进)要执行的命令;
}。。。
(注意缩进不要错,圆括号不要漏;若省略{},则只会判断是否执行紧挨着的第一条语句,其他语句则无视条件测试执行;当且仅当要执行的语句只有一条时,可以省略{})
If语句的表达式。值为1(非0)/0(非0以外的数值=0),分别代表True/False。
(若为名称,在非空时返回1,在空时返回0;若为标志,值为1/0。)
检查是否相等,A == B(相等运算符==)
检查是否不等,A != B(不等运算符!=)
比较数值,A >/>=/</<= B(其他关系/比较运算符>、>=、<、<=)
B赋值给A,数据类型A=B,(赋值运算符=)
把左边的第一个符号移到右边,a += b <=> a = a+b
(复合赋值运算符+=、-=、*=、/=、%=、&=、|=、<<=、>>=;常用于多行字符串)
检查特定值是否包含在列表中,特定值 in 列表
检查特定值是否不包含在列表中,特定值 not in 列表
反向条件,!A(逻辑非运算符!)
检查多个条件,条件测试A &&/|| 条件测试B(逻辑与运算符&&,逻辑或运算符||)
(分支跳转;多个条件,只检查1个条件,只执行1个操作)
switch (控制表达式) {
(缩进)case 常量:
(缩进)(缩进)要执行的命令;
(缩进)(缩进)break;
。。。
(缩进)default:
(缩进)(缩进)要执行的命令;
(缩进)(缩进)break;
}
(注意缩进不要错,圆括号、冒号不要漏;若省略{},则只会判断是否执行紧挨着的第一条语句,其他语句则无视条件测试执行;当且仅当要执行的语句只有一条时,可以省略{})
①while循环(先条件判断,后进循环体;可以一次都不做;条件测试内容相同)
while (条件测试) {
(缩进)要执行的命令;
}
(注意缩进不要错,圆括号不要漏;若省略{},则只会判断是否执行紧挨着的第一条语句,其他语句则无视条件测试执行;当且仅当要执行的语句只有一条时,可以省略{})
②do-while循环(先进循环体,后条件判断;至少做一次;条件测试内容相同)
do {
(缩进)要执行的命令;
} while (条件测试);
(注意缩进不要错,圆括号、分号不要漏;若省略{},则只会判断是否执行紧挨着的第一条语句,其他语句则无视条件测试执行;当且仅当要执行的语句只有一条时,可以省略{})
for循环:——设定有限次循环(计数器)
for (条件初始化;条件测试;条件改变) {
(缩进)对临时变量进行命令
}
(注意缩进不要错,圆括号不要漏;若省略{},则只会判断是否执行紧挨着的第一条语句,其他语句则无视条件测试执行;当且仅当要执行的语句只有一条时,可以省略{})
跳出循环/开关 break
(无视余下代码,无视条件改变和条件测试;循环条件测试为True的唯一结束方式)
继续循环 continue
(无视余下代码,重新进行条件改变和条件测试)
跳出多重循环:
法1:接力break,初始化标志exit=0,,若break则为1
法2:goto语句,标号goto; 标号:
注:①while循环和for循环是等价的,while (条件测试) == for (;条件测试;)
②三种循环的选择:
获取用户输入:
获取字符串输入 input(提示)(提示告诉用户应该怎么做,“文本 ”)
将浮点数或字符串转换为整数 int(浮点数/表示整数的字符串)
将整数和字符串转换成浮点数 float(整数/表示浮点数的字符串)
多文件管理——工作区
S1 创建目录:新建文件夹,在程序中打开文件夹
S2 添加内容:在目录中新建文件/文件夹
S3 多文件编译:
打开查看 -终端,
显示文件列表 dir
执行程序 .\程序
若文件较少,用gcc编译文件成为程序:gcc 文件1 文件2 -o 程序
若文件较多,用makefile管理:mingw64-make
编译文件:gcc 文件
编译但不链接:gcc -c 文件(.c->.o)
指定输出文件名:gcc -o 输出文件名 文件
(将生成可执行程序输出文件名,否则默认输出a.out)(.c->.out)
保存编译过程中的临时文件:gcc --save-temps 文件
查看文件末尾若干行代码:tail -n 行数 文件(若省略红字,则为少数几行;仅linux可用)
三、IDE(集成开发环境,Integrated Development Environment)
关于DevC++如何调试的问题,还不会调试的同学看这里--->>>超级详细调试教程,手把手教你如何调试_落雨归林的博客-CSDN博客_devc++调试
若需要多文件编译,
S1 新建项目,确定语言类型并保存
S2 在左边项目下,右键移除多余文件,右键添加所需要的文件 S3 点击编译
用C++语言,在其上开发图形界面,包括很多用于显示Windows图形界面的库函数