c和c++
🌱 一些记录? 🌱
快捷导航
数据类型
| 基本类型 | 构造类型 | 指针类型 * |
空类型 void |
|---|---|---|---|
整型 int |
数组 [] |
||
实型(浮点型) float |
结构体 struct |
||
字符型 char |
整型不同类型
| 类型 | 类型说明符 | 长度 | 整型数的范围 |
|---|---|---|---|
| 基本整型 | int |
4字节 |
-2^31 ~ 2^31-1 |
| 短整型 | short (int) |
2字节 |
-2^15 ~ 2^15-1 = 32767 |
| 长整型 | long (int) |
32位为4字节,64位为8字节 |
-2^31 ~ 2^31-1 或 -2^63 ~ 2^63-1 |
| 无符号整型 | unsigned int |
4字节 |
0 ~ 2^32-1 |
| 无符号短整型 | unsigned short (int) |
2字节 |
0 ~ 2^16-1 = 65535 |
| 无符号长整型 | unsigned long (int) |
32位为4字节,64位为8字节 |
0 ~ 2^32-1 或 0 ~ 2^64-1 |
浮点型不同类型
| 类型 | 长度 | 数值范围 | 有效数字(精度) |
|---|---|---|---|
单精度float型 |
4字节 |
10^−37 ~ 10^38 或 2^−126 ~ 2^127 |
6 ~ 7 位(因为 23 位二进制来表示) |
双精度double型 |
8字节 |
10^−307 ~ 10^308 或 2^−1022 ~ 2^1023 |
15 ~ 16 位(因为 52 位二进制来表示) |
常量
常量类型
常量是指在程序运行过程中,其值不发生变化的量
用
单引号括起来的一个字符是字符型常量,且只能包含一个字符!字符串型常量是由
一对双引号括起来的字符序列字符型常量为
1个字节字符串型常量为
字符数+1个字节(因有'\0')
| 整型 | 实型 | 字符型 | 字符串型 |
|---|---|---|---|
| 1 | 0.003, 3e-3 | ‘a’, ‘1’, ‘ ‘, ‘\n’ | “a”, “abc” |
符号常量
1 |
|
1 | i=5 |
变量
- 命名规定:C语言规定标识符只能由
字母、数字和下划线三种字符组成
并且第一个字符必须为字母或下划线。
scanf函数
存在缓冲区, 缓冲区无则阻塞- scanf匹配
%d,%s或%f前会在缓冲区从左往右删除\n,空格等字符 fflush(stdin);//清空标准输入缓冲区- scanf返回匹配成功的数量
- 多个匹配时,如果输入时加空格分隔,
%c前加空格, 如scanf("%d %c%f",&i,&c,&f); 读取double类型时,要用%lf
printf函数
- 无符号类型要用
%u %f即可以输出float,也可以输出double
1 |
|
1 | d=11, f=0.005000, c=c, s=string, |
整型常量的不同进制表示
1个字节(byte),是8个位(bit), 如:01010101- 1KB =1024字节
- 1MB =1024KB
- 1GB =1024MB
十六进制 0-9 a-f- 程序运行时,整型是以二进制在内存中存储的
- 十进制,八进制,十六进制是为了人类使用在设计的
- 十进制是0-9,八进制是0-7,十六进制是0-9 A-F
运算符
[] () . ->>- ~ ++ -- * & ! (type) sizeof!>* / %>+ -><< >>>关系运算符关系运算符>&>^>|>&&>||>?:?:>赋值运算符>,
| 优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 |
|---|---|---|---|---|---|
| 1 | [] | 数组下标 | 数组名[常量表达式] | 左到右 | |
| 1 | () | 圆括号 | (表达式)/函数名(形参表) | 左到右 | |
| 1 | . | 成员选择(对象) | 对象.成员名 | 左到右 | |
| 1 | -> | 成员选择(指针) | 对象指针->成员名 | 左到右 | |
| 2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
| 2 | ~ | 按位取反运算符 | ~表达式 | 右到左 | 单目运算符 |
| 2 | ++ | 自增运算符 | ++变量名/变量名++ | 右到左 | 单目运算符 |
| 2 | -- | 自减运算符 | --变量名/变量名-- | 右到左 | 单目运算符 |
| 2 | * | 取值运算符 | *指针变量 | 右到左 | 单目运算符 |
| 2 | & | 取地址运算符 | &变量名 | 右到左 | 单目运算符 |
| 2 | ! | 逻辑非运算符 | !表达式 | 右到左 | 单目运算符 |
| 2 | (类型) | 强制类型转换 | (数据类型)表达式 | 右到左 | |
| 2 | sizeof | 长度运算符 | sizeof(表达式) | 右到左 | |
| 3 | / | 除 | 表达式/表达式 | 左到右 | 双目运算符 |
| 3 | * | 乘 | 表达式*表达式 | 左到右 | 双目运算符 |
| 3 | % | 余数〈取模) | 整型表达式%整型表达式 | 左到右 | 双目运算符 |
| 4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
| 4 | - | 减 | 表达式-表达式 | 左到右 | 双目运算符 |
| 5 | << | 左移 | 变量<<表达式 | 左到右 | 双目运算符 |
| 5 | >> | 右移 | 变量>>表达式 | 左到右 | 双目运算符 |
| 6 | > | 大于 | 表达式>表达式 | 左到右 | 双目运算符 |
| 6 | >= | 大于等于 | 表达式>=表达式 | 左到右 | 双目运算符 |
| 6 | < | 小于 | 表达式<表达式 | 左到右 | 双目运算符 |
| 6 | <= | 小于等于 | 表达式<=表达式 | 左到右 | 双目运算符 |
| 7 | == | 等于 | 表达式==表达式 | 左到右 | 双目运算符 |
| 7 | != | 不等于 | 表达式!=表达式 | 左到右 | 双目运算符 |
| 8 | & | 按位与 | 表达式&表达式 | 左到右 | 双目运算符 |
| 9 | ^ | 按位异或 | 表达式^表达式 | 左到右 | 双目运算符 |
| 10 | | | 按位或 | 表达式|表达式 | 左到右 | 双目运算符 |
| 11 | && | 逻辑与 | 表达式&&表达式 | 左到右 | 双目运算符 |
| 12 | || | 逻辑或 | 表达式||表达式 | 左到右 | 双目运算符 |
| 13 | ?: | 条件运算符 | 表达式1?表达式2:表达式3 | 右到左 | 三目运算符 |
| 14 | = | 赋值运算符 | 变量=表达式 | 右到左 | |
| 14 | /= | 除后赋值 | 变量/=表达式 | 右到左 | |
| 14 | *= | 乘后赋值 | 变量*=表达式 | 右到左 | |
| 14 | %= | 取模后赋值 | 变量%=表达式 | 右到左 | |
| 14 | += | 加后赋值 | 变量+=表达式 | 右到左 | |
| 14 | -= | 减后赋值 | 变量-=表达式 | 右到左 | |
| 14 | <<= | 左移后赋值 | 变量<<=表达式 | 右到左 | |
| 14 | >>= | 右移后赋值 | 变量>>=表达式 | 右到左 | |
| 14 | &= | 按位与后赋值 | 变量&=表达式 | 右到左 | |
| 14 | ^= | 按位异或后赋值 | 变量^=表达式 | 右到左 | |
| 14 | |= | 按位或后赋值 | 变量|=表达式 | 右到左 | |
| 15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 |
赋值运算符
- 为了理解有些操作符存在的限制,必须理解左值 (L-value)和右值(R-value)之间的区别
左值是那些能够出现在赋值符号左边的东西,右值是那些可以出现在赋值符号右边的东西a+25不能作为左值,因为它并未标识一个特定的位置(并不对应特定的内存空间)
复合赋值运算符
- 赋值运算符与复合赋值运算符的区别如下:
- 复合赋值运算符简化了程序,可使程序精炼,提升阅读速度
- 复合赋值运算符提高了编译效率
逻辑运算符与逻辑表达式
- 逻辑运算符!、&&、||依次为
逻辑非、逻辑与、逻辑或,这和数学上的与、或、非是一致的 - 逻辑非的优先级高于算术运算符,逻辑与和逻辑或的优先级低于关系运算符
逻辑表达式的值只有真和假,对应的值为1和0对О取非,得到的值为1;对非О值取非,得到的值为0(3<a && a<10);//a大于3同时a小于10要这样写
短路运算
逻辑与短路运算是当前面一个表达式为假时,后面的表达式不会得到执行逻辑或短路运算是当前面一个表达式为真时,后面的表达式不会得到执行
1 |
|
sizeof
- 运算符,不是函数
- 可以用来计算某个变量的空间大小
强制类型转化:(数据类型)
1 |
|
1 | 2.000000 |
条件运算符
- 条件运算符是C语言中唯一的一种
三目运算符,三目运算符代表有三个操作数 运算符也称操作符三目运算符通过判断问号之前的表达式的真假,来确定整体表达式的值
1 |
|
1 | 1 2 |
逗号运算符
- 逗号运算符的优先级最低
逗号表达式的整体值是最后一个表达式的值
1 |
|
1 | i = 6, j = 9 |
自增自减运算符
- 自增、自减运算符和其他运算符有很大的区别,因为其他运算符除赋值运算符可以改变变量本身的值外,不会有这种效果
- 自增、自减就是对变量自身进行加 1 ,减 1 操作
- 因为自增、自减会改变变量的值,所以自增和自减不能用于常量
1 |
|
1 | i=9,j=1 |
位运算符
位运算符只能用于对整型数据进行操作左移(<<):高位丢弃,低位补0,相当于乘以2- 例如要申请1GB大小的空间,可以使用malloc(1<<30)
右移(>>):低位丢弃,正数的高位补0(无符号数我们认为是正数),负数的高位补1,相当于除以2移位比乘法和除法的效率要高右移,对偶数来说是除以2,但对奇数来说是先减1后除以2- 例如,-8>>1,得到的是-4,但-7>>1 得到的并不是-3 而是-4。
对于-1 来说,无论右移多少位,值永远为-1对有、无符号数进行右移,结果不一样
一个变量移动以后自身不会变化
c语言的左移和右移相当于是算术左移与算术右移,而逻辑左移与右移空位都补0按位异或(^):相同的数进行异或时,结果为0,不同为1任何数和零异或得到的是自身两个相等的数异或得到的是零可以在一堆数中找出出现1次的那个数
按位取反(~):数位上的数是1变为0,0变为1按位与(&)和按位或(|):用两个数的每一位进行与和或
1 |
|
1 | i=5, j=10 |
数组
一维数组
推荐写法
1 | int a[3]={0,1,2}; |
1 | int a[]={0,1,2}; |
1 | int a[5]={0,1,2};//后两个数为0 |
1 | int a[3]={0,0,0};//全为0 |
1 | int a[3]={0};//全为0 |
访问越界
1 |
|
1 | i=7 |
字符数组
推荐写法
1 | char s[7] = "string"; |
1 | char s[7] = {'s','t','r','i','n','g'}; |
打印乱码
- 因为
printf通过%s打印字符串时,原理是依次输出每个字符,当读到结束符'\0'时,结束打印
1 |
|
1 | string |
gets函数与puts函数
1 |
|
1 | string string string |
str 系列字符串操作函数
- strlen(string);//统计字符串的长度
- strcat(string, xyz);//把xyz中的字符串拼接到string中
- strcpy(abc, string);//把string中的字符串复制到abc中
- strcmp(string, xyz);//前者<后者,负值;相等,0;前者>后者,正值(比较ASCII)
1 |
|
1 | strlen(string)=6 |
二维数组
二维数组定义的一般形式如下:
1
类型说明符 数组名[常量表达式][常量表达式];
例如,定义a为3×4(3行4列)的数组,b为5×10(5行10列)的数组
1
float a[3][4], b[5][10];
二维数组中的元素在内存中的存储规则是按行存储,即先顺序存储第一行的元素,后顺序存储第二行的元素,直到最后一行
1 |
|
1 | sizeof(a)=48 |
指针
- 内存区域中的每字节都对应一个编号,这个编号就是
地址 - 如果在程序中定义了一个变量,那么在对程序进行编译时,系统就会给这个变量分配内存单元
- 按变量地址存取变量值的方式称为
直接访问,如printf("%d", i);、scanf("%d",&i); - 另一种存取变量值的方式称为
间接访问,即将变量i的地址存放到另一个变量中 - 在C语言中,
指针变量是一种特殊的变量,它用来存放变量地址。
指针与指针变量是两个概念
- 一个变量的
地址称为该变量的指针。例如,地址2000是变量i的指针 - 如果有一个变量专门用来存放另一变量的地址(即指针),那么称它为
指针变量
sizeof(指针)
64位,指针8字节32位,指针4字节
取地址操作符与取值操作符
取地址与取值(引用与解引用)
1 |
|
1 | i=1 |
指针的传递
1 |
|
1 | before change i=10 |
指针的偏移
- 指针变量加1后,偏移的长度是其基类型的长度
1 |
|
1 | 1 2 3 4 5 |
指针与动态内存申请
- 数组长度固定是因为其定义的整型、浮点型、字符型变量、数组变量都在栈空间中
- 而栈空间的大小在编译时是确定的
如果使用的空间大小不确定,那么就要使用堆空间堆的效率要比栈低得多栈空间由系统自动管理,而堆空间的申请和释放需要自行管理任何指针均可自动转为(void*)类型指针
1 |
|
1 | 99 |
栈空间与堆空间的差异
1 |
|
1 | I am print_stack func |
二级指针
1 |
|
1 | sizeof(p2)=8 |
函数
函数如果不显式地声明返回值的类型,那么它默认返回整型- 一个源程序文件由一个或多个函数及其他有关内容(如命令行、数据定义等)组成
- 一个源程序文件是一个编译单位,在程序编译时是以源程序文件为单位而不是以函数为单位进行编译的
- 分别编写、分别编译,进而提高调试效率
- 所有函数都是平行的,即在定义函数时是分别进行的,并且是互相独立的
一个函数并不从属于另一函数,即函数不能嵌套定义- 函数间可以互相调用,但不能调用main函数,main函数是由系统调用的
函数的声明与定义的差异:
- 函数的定义是指对函数功能的确立,包括指定函数名、函数值类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。
- 函数的声明的作用是把函数的名字、函数类型及形参的类型、个数和顺序通知编译系统, 以便在调用该函数时编译系统能正确识别函数并检查调用是否合法。
嵌套调用
递归调用
- 我们把函数自身调用自身的操作,称为递归函数
递归函数一定要有结束条件,否则会产生死循环!
1 | 假如有n个台阶,一次只能上1个台阶或2个台阶,请问走到第n个台阶有几种走法? |
1 |
|
1 | 5 |
局部变量与全局变量
全局变量存储在数据段- 全局变量不会因为某个函数执行结束而消失,在整个进程的执行过程中始终有效
局部变量存储在自己的函数对应的栈空间内函数执行结束后,函数内的局部变量所分配的空间将会得到释放如果局部变量与全局变量重名,那么将采取就近原则,即实际获取和修改的值是局部变量的值- 定义函数中指定的形参,如果没有函数调用,那么它们并不占用内存中的存储单元
- 实参可以是常量、变量或表达式,但要求它们有确定的值
实参向形参的数据传递是单向值传递,只能由实参传给形参- 在调用函数时,给形参分配存储单元,并将实参对应的值传递给形参,调用结束后,形参单元被释放,实参单元仍保留并维持原值。
1 |
|
1 | main i=5 |
结构体
结构体的定义、初始化、结构体数组
1 |
|
1 | lele p 666 66.599998 |
结构体对齐
结构体的大小必须是其最大成员的整数倍!如果相邻两个小存储之和小于最大长度,那么它们就结合在一起
1 |
|
1 | s1 size=16 |
结构体指针
1 |
|
1 | 1 lele p |
typedef
1 |
|
1 | p->num=666 |
C++的引用讲解
- 修改函数外的某一变量时,使用了引用后,在子函数内的操作和函数外操作手法一致,这样编程效率较高
1 |
|
1 | after modify num a=11 |
1 |
|
1 | after modify num a=11 |
1 |
|
1 | after modify pointer *p=10 |
1 |
|
1 | after modify pointer *p=10 |
C++的布尔类型
布尔类型在C语言没有,C++中才有bool类型,分别是true和false- 布尔值的好处是提升了代码的可阅读性
1 |
|
1 | a=1,b=0 |
switch选择语句
switch的case后只能放常量表达式- case后如果没有break,那么不会匹配后面的case的表达式,直接对应表达式后的语句
1 |
|
1 | 2000 2 |
do while 循环
1 |
|
1 | total=5050 |
题合集
基础题
| 判断题 | 答案 |
|---|---|
| 程序的作用是完成某种计算 | |
| 源代码文件main.c需要编译为最终的可执行文件, CPU才能执行, CPU不能够直接去运行main.c | |
| 常量在执行过程中不可以被修改的,变量在执行过程中才可以修改 | |
| c-clang是一个正确的变量名 | |
| 字符串常量“hello”占用的空间是5个字节 | |
| scanf(%d”,&i),当我们输入10回车后,i读取到了10,那么标准缓冲区中已经空了 | |
| 有如下代码, int i; scanf(“%d”,i);想读取一个数据到变量i中,是否正确 | |
| 当混合读取( )时,因为%c不能忽略空格和\n,所以需要在其前面加一个空格 | |
| %取余(也称为取模运算)可以用于浮点数 | |
| c语言中逻辑表达式的值是真或假,真的值是1,假是0 |
程序题
1 | 输入一个整型数,判断是否是对称 |
1 |
|
1 | 1224221 |
1 | 某人想将手中的一张面值 100 元的人民币换成 10 元、5 元、2 元和 1 元面值的票 |
1 |
|
1 | 34 |
1 | 输入N个数(N小于等于100),输出数字2的出现次数 |
1 |
|
1 | 6 |
1 | 读取一个字符串,字符串可能含有空格 |
1 |
|
1 | hello |
1 | 输入一个整型数,存入变量i,通过子函数change把主函数的变量除2,然后打印 |
1 |
|
1 | 10 |
1 | 输入一个整型数,然后申请对应大小空间内 |
1 |
|
1 | 10 |
1 | 在主函数定义字符指针char *p,然后在子函数内malloc申请空间 |
1 |
|
1 | abc |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 admin🌸!



