C_02基础学习
c 语言 基础
gcc编译器
作用: 将代码文件编译为可执行文件
分类:
一步到位gcc 要编译的代码文件 -o 生成的可执行文件注意:要编译的代码文件可以是多个-o 生成的可执行文件:可以忽略不写,默认生成a.out文件
分步实现预编译:头文件展示,宏替换,选择型编译gcc -E 要编译的代码文件 -o 生成的预编译文件.i编译:检测代码错误,将预编译文件编译为汇编文件gcc -S 预编译文件.i -o 生成的汇编文件名.s汇编:将汇编文件转换为二进制文件gcc -c 汇编文件名.s -o 生成的二进制文件.o链接:将二进制文件与使用的三方文件连接生成可执行文件gcc 二进制文件.o -o 生成的可执行文件名
运行可执行文件
> ./可执行文件名注意:要切换到可执行文件名所在的文件夹
1 .HelloWorld
步骤:
1,创建一个文件,建议其命名为helloworld
- vim helloworld.c
//1. 创建一个文件后缀名为 helloworld.c 注意文件名不要使用中文或者数字开头。 建议 见名知意
//2. 在文件中编写以下代码
#include <stdio.h>
int main(){printf("hello world\n");return 0;
}
// 3. 将该文件 编译为可执行文件 如果代码文件中进行了修改,则需进行从新编译
// 4. 运行可执行文件
- 然后 按 ESC 并输入 wq 保存退出
2 .注释
作用:
1 解释说明
2 注销无用代码
语法:
// 单行注释
/**/ 多行注释 注意 :在多行注释中不能使用多行注释注意: 注释是不会影响代码的运行
3.输入
作用:
//将控制台中的内容录入到程序语法:
scanf("占位符",&变量);使用
键盘录入一个数打印输出int num = 0;scanf("%d",&num); printf("num = %d\n",num) ;
4. 输出
作用:将内容打印到控制台
语法:
printf("要输出的内容",值....);注意:输出的内容中有两种特殊的内容1,转意字符2,占位符后面值的个数由前面内容中占位符的个数决定输出情况:行刷新满刷新关闭刷新
5.转义字符
有特殊含义的字符为转意字符,以\开始,常用的有
\\ \
\" "
\' '
\t 制表
\n 换行
\a 响铃
\0 字符串结束符
6. 占位符
- 作用:占位
%s:字符串占位符
%c:字符占位符
%d:整数占位符
%f:浮点数占位符
%p:指针占位符
%x:十六进制数占位符特殊应用:
%3d %03d %-3d %.2f
%3d:要求宽度为 3 位,如果不足 3 位,前面空格补齐;如果足够 3 位,此语句
无效
%03d:要求宽度为 3 位,如果不足 3 位,前面 0 补齐;如果足够 3 位,此语
句无效
%-3d: 要求宽度为 3 位,如果不足 3 位,右对齐后面空格补齐;左对齐前面3位
补空格,如果足够 3 位,此语句无效
%.2f:小数点后只保留 2 位
7.关键字
目的: 明白那些是关键字
含义: 在代码中有特殊含义的单词,这种单词就成为关键字
注意:学习关键字,为了在起标识符时 不要使用。明白关键字的意义。

8. 标识符
作用: 标记的符号 用于变量名 常量名函数名 结构体名称等 只要带名 就是标识符;
规则:
自定义设定
强制规则: 1 不能使用数字开头2 不能使用关键字3 不能使用特殊符号 【 _ 与 $ 符号除外】4 不建议使用中文 也就是可以使用
潜规则::见名知意1 linux风格[c的常用] 多个单词之间以下划线 _ 连接 例如 hello_world 2 驼峰命名法【java 和 c++常用】 小驼峰 一般应用与变量名,函数名,数组名等,对应C与C++中的变量名,函数名,数组名 大驼峰每个单词首字母大写一般应用于类名,枚举名,接口名等可与对应C与C++中的结构体,枚举,类 全大写所有字母全大写一般应用于 常量名 全小写一般应用于应用于包名对应C与C++中存储代码的文件夹
9. 基本数据类型
分类:
- 基本数据类型
- 引用数据类型
整型
short 2 字节 8位 * 2 -2^15~2^15-1 -32768 ~ 32767 超过32767就存不了了
int 4 字节 8位 * 4=32 -2^31~2^31-1 默认使用
long 8 字节 (64位机)/4(32位机) 定义long型时 需要在定义的数据后面加L 或者小写l long i = 30000000000L; 只要超过int型存储的数值 后就加L或者l
浮点型
float 占 4 字节 后加F 或f
double 占 8 字节
字符型
char 占 1 字节 1 字节存储 255 位注意: 单个字符必须使用 '' 包裹如 'a' 'A' '中' 一个单引号 一个字符 char c1 = 'a';char c2 = 'A';char c3 = '\\' # '\\' 这个里面只有一个东西 就是 \ 而不是两个东西# c c++ 中没有 字符串概念 称为 字符数组 也不是基本数据类型特殊字符: 转义字符\\ \'\"\n 换行\a 响铃\t 制表\0 字符串结束最初的计算机 只 有 英文字母 + 阿拉伯数字 + 英文点符号
10. sizeof关键字
作用:
获取数据类型或数据的大小,单位字节
语法:
# sizeof(数据类型或值)
11. 变量
作用:在程序中临时记录一个值可以发生改变的数据
全局变量: 在函数外定义变量 默认值是0
局部变量: 定义在函数中的变量,默认值 随机数 基本是0 使用 auto 修饰
如;
#include <stdio.h>//函数外
int main()
{//函数中return 0;
}//函数外
注意:
全局变量 可以 与 局部变量名相同
当全局变量与局部变量名相同,优先使用局部变量 【就近原则】
使用:
1. 声明 可有可无告知编译器有这个变量,但是此时系统并不会为其开辟内存空间语法: extern 数据类型 变量名;
2. 定义告知系统创建该变量,并为其分配内存语法:数据类型 变量名;【注意】同一个作用域下变量名不能相同;
3. 赋值变量的第一次赋值称为变量的初始化语法:变量名 = 值;【注意】一个变量可以赋值多次等号两边数据类型要相同
4. 使用直接使用变量名语法: 变量名注意:一个变量可以使用多次
12. 数据类型转换
【小类型转换为大类型】 自动转换
char c = 'a' ; // char 字符型 1 字节 int i; // int 是整型 4 字节i = c; // 自动转换语法: 【 大类型变量 = 小类型变量或值; 】
【大类型转换为小类型】 为 强制转换
如:
int i = 97; // int 4b
char c; // char 1b
c = (char) i; // int 转 char 强制转换
语法:【 小类型变量 = (转换后的小类型) 要转换的大类型变量或值; 】注意: 可能回出现数据丢失就类似 小类型变量 为 空水杯大类型变量 为 水桶大==》小 也就是 将水桶的水倒进 空水杯中 存在两种情况1 水桶水刚好或者可以倒进 空水杯中 也就是正常转换2 水桶水多于空水杯容量 那就会造成 溢满的数据丢失 所以要转换的时候考虑到!!!!!!!
13.存储相关关键字
register
作用: 建议寄存器存储
语法: register 数据类型 变量名; 【不建议使用】
> 寄存器存储优点:快
> 注意:寄存器中存储的数据容器较小,所以只会存储高频使用的变量那么如果我们用register修饰的变量不是高频使用的,那么也有可能被寄存器中移除
volatile
作用:使用该关键字修饰的变量,会强制系统从内存中取值
语法: volatile 数据类型 变量名;
经验: 类似于瓦斯浓度、银行钱等使用该关键字修饰。
auto
作用: 自动
语法:
> auto 数据类型 变量名;注意:此时该变量的初始化为随机数局部变量默认使用auto修饰
extern
作用: 声明,告知编译器存在该变量或函数 没有开辟内存
语法: extern 数据类型 变量名;
14.其他关键字
sizeof
typedef
作用: 给已有数据类型起别名
语法: typedef 已有类型 别名;
15. 进制:
二进制
0 1 10 11 100 101 110 111 1000 1001 1010.....# 计算机中 二进制 的数据以 0b 开头 int i= 0b0001; printf("i = %d\n",i);八进制
0 1 2 3 4 5 6 7 10 11 12 13....# 计算机中 八进制 的数据以 0 开头十进制
00 01 02 03 04 05 06 07 08 09 10 11 12......printf输出数据输出的就是10进制数 在计算机直接书写的数都是10进制数十六进制
0 1 2 3 4 5 6 7 8 9 a b c d e f 10# 计算机中 十六进制 的数据以 0x 开头
16.进制转换
10 to 2
- 技巧:十进制数 除以2 取余 余数倒读
132---------6 12---------3 02----------1 12----------1
10 to 8
- 技巧:**十进制数除以8 取余 ,余数倒读 **
13
8
---------
1 5
8
---------1
10 to 16
- 技巧:十进制数除以16 取余,余数倒读
1316---------13
2 to 10
- 技巧: 2进制所在位的数*2^位数-1次幂,相加
0100 1010
1 * 2^6 + 0 * 2^5 + 0 * 2^4 + 1*2^3 + 0*2^2 + 1*2^1 + 0 *2^0
64 + 8 + 2 = 74
8 to 10
- 技巧: 8进制所在位的数*8^位数-1次幂,相加
032
3 * 8^1 + 2 * 8^0
24+ 2
26
16 to 10
- 技巧: 16进制所在位的数*16^位数-1次幂,相加
17.原码反码补码
-
原码:数据对应的 二进制数,称为该数据的原码
-
反码:
正数三码合一,原码=反码=补码
负数符号位不动,其他位依次取反【首位不动】如:10源码:0000 0000 0000 0000 0000 0000 0000 1010反码:0000 0000 0000 0000 0000 0000 0000 1010-10源码:1000 0000 0000 0000 0000 0000 0000 1010反码:1111 1111 1111 1111 1111 1111 1111 0101
- 补码:
正数补码 = 反码 = 源码 [三码统一]
负数补码 = 反码 + 1如:10源码:0000 0000 0000 0000 0000 0000 0000 1010反码:0000 0000 0000 0000 0000 0000 0000 1010补码:0000 0000 0000 0000 0000 0000 0000 1010-10源码:1000 0000 0000 0000 0000 0000 0000 1010反码:1111 1111 1111 1111 1111 1111 1111 0101补码:1111 1111 1111 1111 1111 1111 1111 0110
18.补码的意义
意义一: **统一了 0 与 - 0 **
意义二: **将 减法运算 变 为了 加法运算 **
计算机底层以补码的形式存储数据

19.计算机的存和取
存数据: 数据(10进制) -》 原码(二进制) -》 反码 -》补码
取数据: 补码 -》 反码 -》 原码(二进制) -》 数据(10进制)
int x = 0x8000 0001; 1000 0000 0000 0000 0000 0000 0000 0001 1000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1111 1111 printf("x = %d\n",x); 此时我们会发现出现的值为负数与存的值不同
运算符
作用:
运算的符号
算数运算
+ 加 - 减 * 乘 / 除 % 取余++ 递增++ 在前, 先递增再参与运算流程: 3步取值+1 赋值int a =1;a++; a=1a = a+1a = a;++ 在后, 先运算后自增流程: 4步取值:+1赋值:使用取值参与运算 -- 递减-- 在前, 先自减再运算-- 在后, 先运算后自减
注意:
- 小类型与小类型运算,结果为小类型
如:1 / 2 = 0; double c = 1 / 2;
- 小类型与大类型运算,结果为大类型
double c = 1 / 2.0;
赋值运算符
- =
- 作用:将等会右边的值,赋值给左边的变量
复合运算符
+= -= *= /= %=
关系运算符
< 小于 > 大于 <= 小于或等于 >= 大于或等于 == 判断是否相等 'a' == 97 != 判断是否不等 'a' != 97注意:
- 除0以外都是真
- 0 为 假
位运算符
| 或有1为1,全0为02 | 8 = 10001010001010& 与全1为1 ,有0为02 & 8 = 0001010000000~ 取反0变1 , 1变0~20000 0000 0000 0000 0000 0000 0000 00101111 1111 1111 1111 1111 1111 1111 11011111 1111 1111 1111 1111 1111 1111 11001000 0000 0000 0000 0000 0000 0000 0011-3 ^ 异或相同为0 ,不同为12 ^ 8 = 10001010001010>> 右移分类:【取决于计算机】逻辑右移 高位补0 低位溢出算数右移 高位补符号位, 低位溢出4 >> 20000 0000 0000 0000 0000 0000 0000 01000000 0000 0000 0000 0000 0000 0000 0001-4 >> 21000 0000 0000 0000 0000 0000 0000 0100逻辑右移:0010 0000 0000 0000 0000 0000 0000 0001算数右移:1110 0000 0000 0000 0000 0000 0000 0001<< 左移4 << 20000 01000001 00001 << 2;0000 00010000 0100 计算 2^101 << 10
逻辑运算符
&& 短路与同真为真,有假为假|| 短路或有真为真,同假为假! 非非真为假,非假为真
三目运算符
条件表达式 ?值1:值2条件表达式:结果为真或假的表达式关系运算符逻辑运算符 执行流程:当条件表达式值为真,取值1,反之取值2
逗号运算符
, 如变量的定义,形参,实参等 如: int a; int b; int c;int a,b,c;优先级最低优先级最低
运算符优先级

- 不要将多个运算符在一个表达式中使用,尽量拆开
- 如果非用不可加 ( )
语句分类:
- 顺序语句
- 代码从上向下依次执行
- 分支语句
- 用于判断,使代码在多个之间选择一个执行
- 循环语句
- 用于重复执行
分支语句
作用:
表示判断
分类
- if
- switch
if
1 基本if结构if(条件表达式){当条件表达式为真,执行此处代码} 2 if else 结构if(条件表达式){当条件表达式为真,执行此处代码}else{当条件表达式为假,执行此处代码} 3 else if 结构if(条件表达式){当条件表达式1为真,执行此处代码}else if(){当条件表达式2为真,执行此处代码}else{当条件表达式为假,执行此处代码}结合:
if(条件表达式1) {当条件表达式1为真,执行此处代码 } else if(条件表达式2) {当条件表达式2为真,执行此处代码 } else if(条件表达式3) {当条件表达式3为真,执行此处代码 } ... else if(条件表达式n) {当条件表达式n为真,执行此处代码 } else {当以上条件表达式都为假,执行此处代码 } 注意:if 可以单独存在,一个 if 结构中必须也只能有一个 ifelse if 不能单独存在,一个 if 结构中可以有多个 else ifelse 不能单独存在,一个 if 结构中最多只能有一个 else如果多个条件表达式都为真,只执行最上面的那个
switch
switch(变量) {case 常量1:代码1:当变量值等于常量1时,执行此处代码 //break;case 常量2:代码2:当变量值等于常量2时,执行此处代码break;case 常量3:代码3:当变量值等于常量3时,执行此处代码break;...case 常量n:代码n:当变量值等于常量n时,执行此处代码break;default:代码n+1:当变量值不等于以上所有常量,执行此处代码break; }注意:
- 常量值不能相同
- 常量:写死的值或不能修改值的变量称为常量
- break:跳出当前代码块,可有可无,如果没有导致贯穿
- 代码块:一个 { } 就是一个代码块
- default:可有可无,最多只能有一个
- case : 可有可无,可以有多个
随机数
作用:随机获取一个数
步骤:
1 引入头文件
#include <stdib.h> #include <time.h>2 设置随机数种子
srand(time(NULL)); // 一个程序只需要设置一次3 获取随机数
rand(); //取值范围就是0 ~ int的最大值#include <stdio.h> #include <stdlib.h> //引入头文件 #include <time.h> //引入头文件int main(int argc, char const *argv[]) { srand(time(NULL)); //设置随机数种子int a = rand();printf("a = %d\n",a);//随机获取0-10之间随机数int x = rand()%11;printf("x = %d\n",x);//随机获取0-50之间随机数int y = rand()%51;printf("y = %d\n",y);//随机获取65-90之间随机数int z = rand()%26+65;printf("z = %d\n",z);//随机生成一个大写字母int d = rand()%26+65;char dx = (char)d;printf("dx = %c\n",dx);return 0;}
循环语句
作用:
重复执行一段代码
优点:
降低代码冗余度, 提高代码复用率, 提升开发效率
分类
while do while for
while
语法:while(条件表达式){循环体: 重复执行的代码} 执行流程:先判断条件表达式是否为真如果为真,执行循环体中的代码,如果为假结束循环当循环体中的代码执行完毕后,再次判断条件表达式是否为真如果为真,执行循环体中的代码,如果为假结束循环......
死循环
条件表达式永远为真的循环,称为死循环
while(1) {}
do while
do { 循环体 }while(条件表达式); 执行流程:先执行一次循环体,在判断条件表达式是否为真如果为真,再次执行循环体,如果为假,结束循环 当循环体执行完毕后,再次判断条件表达式是否为真......
for
for (表达式1;条件表达式2;表达式3) {循环体4 }表达式1:初始化变量条件表达式2:循环条件表达式3:修改变量循环体4:重复执行的代码执行流程:1 2 4 3 2 4 3 ......2#include <stdio.h> #include <time.h> #include <stdlib.h> int main(int argc, char const *argv[]) { //生成10个随机数 srand(time(NULL)); for (int i = 0; i < 10; i++){int x = rand();printf("%d\n",x); } return 0; }

循环嵌套
在循环语句的循环体中写循环语句,称为循环嵌套。
不建议超过三层
流程控制语句
continue :
跳过本次循环
#include <stdio.h> int main(int argc, char const *argv[]) { for (int i = 0; i < 3; i++) {printf("xxxx\n");continue; //会跳出本次循环 去执行下一次循环 所以只打印了xxxxxprintf("yyyy"); } return 0; }
break
跳出本次循环
goto
跳转至指定位置
#include <stdio.h> int main(int argc, char const *argv[]) { printf("1\n"); goto xx;printf("2\n");printf("3\n");printf("4\n");xx:printf("标签处\n");return 0; }
return:
-
结束当前函数
return 值或变量;结束当前函数并返回该值或变量,此时这个值或变量就是返回值


