基本程序结构
包括
- 预处理
- 函数
- 变量
- 语句,表达式
- 注释
最简单的例子
1 |
|
数据类型,运算符
数据类型
序号 | 描述 |
---|---|
1 | 基本类型 |
2 | 枚举类型 |
3 | void |
4 | 派生类型 |
整数类包括
- char
- unsinged char
- signed char
- int
- unsigned int
- short
- unsigned short
- long
- unsigned long
浮点类包括
- float
- double
- long double
void 类为空类型,用于函数不返回或不输入,以及指针类型
类型转换包括强转和自动转换,自动转换只能从内存少数据类型转向内存多数据类型,如果由内存多数据转向少内存数据将会抹去尾数.
变量常量
c语言变量必须声明,可以在声明时定义并初始化如int a;
,也可以不定义也不初始化如extern int b;
.一个变量必须在定义后才能使用(被分配了内存)
顺便提一下内存
- 栈:系统自动管理,操作方式类似于栈.
- 堆:受到手动管理的内存区域,若申请内存后没有释放将在程序结束后释放.
- 全局静态:用于放置全局变量和静态变量,程序结束后会释放
运算符
包括逻辑运算,位运算,基础运算,赋值运算,比较运算
位运算:按位异或^,按位与&,按位或|,<<,>>
逻辑运算:与&&,或||,非!(编译器会优化运算过程,当与中有一个为假时会停止,或中有一个为真时也会停止)
基础运算:包括+ - * / ++ —
赋值运算:包括=,+=,-=,/=,*=,^=,&=,|=,<<=,>>=
比较运算:包括>,<,==,>=,<=,!=
其他运算:包括 , , (),[]等等
算法
分支
if分支语法
1 | if(condition1) |
switch分支语法
1 | switch(num) |
注意,switch中的case条件应当为常量(不然你让编译器怎么优化)
三目运算符
(帅但是有病)
1 | a?b:c; |
循环
for循环
如
1 | int i; |
while循环
如
1 | while(1) |
break
用于跳出当前循环语句,并进入下一条语句。
continue
用于结束本轮循环,并进入下一轮循环。
goto
谁再让我看见用这个像尸体一样恶臭的上古遗物来污染现代化逻辑语句,以为自己飞雷神一样跳来跳去很厉害的,我TM*******。
1 | goto label; |
迭代递归
原理是在函数自己调用自己,用好了很方便,用不好天天爆栈。
写一个求阶乘的函数吧。
1 |
|
函数
函数基本构成是这样的
1 | return_type funcation_name(input_type name){ |
传入值
传入值分两种,一种是传值,一种是传指针。
由于作用域问题,传值后会在函数的作用域内新申请一个内存,所以函数内修改传入值并不会修改原来的值。
但是传指针是直接操作堆内存,传入的指针是传入指,但是可以直接修改原来的内存,所以可以修改原来的值。
指针
一种储存内存位置的变量,可以修改这个变量指向的内存。
指针在使用时避免读取野指针,空指针的情况。
malloc用于申请一块连续内存,不做初始化。
calloc用于申请按块分配的初始化过(用0)的内存。
数组
数组是一种数据结构,申请一块连续的内存空间,并用指针进行访问。数组的表头本质上是一种指针,但是在作用域中作为一种特殊的数据类型,并不能直接当指针使用
字符串
字符串本质上是一种字符串数组,特征为字符串末尾用\0来标志字符结束。
结构体
使用方式
1 | struct example{ |
或
1 | typedef struct example { |
区别在于前者定义一个结构体并创建了一个该结构体类型的变量,后者创建了一个结构体数据类型。
可以有指向结构体的指针,结构体内也可以存有指针成员,于是就有了链表,二叉树等等。
预处理
宏定义
1 |
本质上是对源文件中的字符进行替换,所以进行替换时运算过程中方程式会直接替换而不会优先运算宏内容。
文件读写
打开文件
1 | FILE* file = fopen( const char *filename, const char *mode ); |
关闭文件\
注意,不要重复关闭文件,否则导致内存重复释放运行时错误。
1 | fclose(file); |
读写文件\
用fgets,fputs,fsanf,fprintf等函数。