5 minutes
C语言基础 笔记
C语言基础
概述
main函数
main函数是C语言的主函数,每个C语言程序都必须存在一个main函数,因为在程序开始的时候就会调用,它是程序执行的起点,当main函数的类型为int的时候表示函数返回一个整数值,类型为VOID表示函数不接受任何参数。main函数的函数体包括左花括号和右花括号之间的任何内容。
printf函数
printf()
函数是格式化输出函数,一般用于向标准输出设备按规定格式输出信息
printf()
函数的调用格式为:printf("<格式化字符串>, <参量表>")
格式输出,它是c语言中产生格式化输出的函数(在stdio.h中定义)。用于向终端(显示器、控制台等)输出字符。格式控制由要输出的文字和数据格式说明组成。要输出的文字除了可以使用字母、数字、空格和一些数字符号以外,还可以使用一些转义字符表示特殊的含义。主要包括%d, %o, %x, %g, %c, %s, 以及换行符\n
空白与注释
空白在C语言里并没有什么特殊的约定来限制你的使用,它的作用仅仅只是似的程序更好理解,更好的显示出程序的结构,仅此而已
在C语言里存在以下两种注释方式
// 单行注释
/*多行注释*/
基础介绍
运行机制:C语言–> 汇编语言–>机器语言–>CPU
编译型语言VS解释性语言
- 编译型语言:编译为可执行文件,直接由CPU执行
- 解释型语言:编译为字节码,由解释器交给CPU执行
程序执行
- 编写
gcc test.c -o test
编译./test
执行
格式化输入
#include <studio.h>
int main(){
printf('hello world');
return 0;
}
输入输出函数
输入函数 scanf("%?", temp);
输出函数 printf("%?", temp);
转义字符
转义字符 | 含义 |
---|---|
\a |
响铃(BEL) |
\b |
退格(BS),将当前位置移到前一列 |
\f |
换页(FF),将当前位置移到下页开头 |
\n |
换行(LF),将当前位置移到下一行开头 |
\r |
回车(CR),将当前位置移到本行开头 |
\t |
水平制表(HT),跳到下一个TAB位置 |
\v |
垂直制表 |
\\ |
表示(\ ) |
\' |
表示(‘ ) |
\" |
表示(“ ) |
\? |
表示(? ) |
\0 |
表示空字符(NULL ) |
\ddd |
1到3位八进制数所代表的任意字符 |
\xhh |
1到2位十六进制所代表的任意字符 |
占位字符
关键字与保留标识符
关键字
变量常量命名不能使用
32个关键字
标识符
-
以下划线开始的标识符,例如:
_Bool
、_Complex
、_Imaginary
-
语言标准库函数名,例如:
printf()
scanf()
strlen()
strcpy()
命名规则
匈牙利命名法
-
变量名前,加上属性、类型
-
变量命名有意义
-
驼峰命名法
-
大驼峰命名法
所有单词全部首字母大写
-
小驼峰命名法
除了第一个单词小写外,其他的单词首字母大写
-
变量常量
变量
变量的意义就算确定目标并提供存放的空间
变量名
- 变量名只能三英文字母(A-Z,a-z)和数字(0-9)或者下划线(_)组成
- 第一个字母必须三字母或者下划线开头
- 变量名区分大小写
数据类型
-
char
字符型,占用一个字节
-
int
整型,通常反映了所用机器中整数的最自然长度
-
float
单精度浮点型
-
double
双精度浮点型
声明变量的语法
int a;
char b;
float c;
double d;
变量赋值方式
方式一:
int a, b, c;
a = 1;
b = 2;
c = 3;
方式二:
int a = 1;
int b = 2;
int c = 3;
方式三:
int a = 1, b = 2, c = 3
常量
类型
- 整型常量:520,1314,123
- 实型常量:3.14,5.12,8.97
- 字符常量
- 普通字符:‘L’,‘o’,‘v’,’e‘
- 转义字符:‘\n’,’\t‘,‘\b’
- 字符串常量:“FishC”
定义符号常量
-
格式:
#define 标识符 常量
-
比如:
#define URL 'http://www.fishc.com'
一般用小写字母命名变量,用大写字母命名常量
标识符
命名规则同变量的命名规则 [[C-basic#变量|变量]]
字符串常量
-
字符:‘F’, ’i’, ‘s ‘ , ‘h’ , ‘C’
-
字符串:
- “Hello world”
- “I love FishC.com!”
编译过程中会将字符串最后一个字符后面添加一个
\0
的空字符,用于判断字符串结束
数据类型
-
基本类型
-
整数类型
int
short int <= int <= long int <=long long int
-
浮点数类型
float double
float
double
long double
-
字符类型
char
-
布尔类型
_Bool
C99之前C语言没有布尔类型,需要引用
#include <stdbool>
-
枚举类型
enum
-
-
指针类型
type *
-
构造类型
- 数组类型
- 结构类型
union
- 联合类型
struct
-
空类型
整型
signed和unsigned
signed
:可以储存负值
unsigned
:只能储存正值及0
[signed] short [int];
unsigned short [int];
[signed] int;
unsigned int;
取值范围
二进制
-
比特位
CPU能读懂的最小单位——比特位,bit,b
-
字节
内存机构的最小寻址单位——字节,Byte,B
1 Byte == 8 bit
计算技巧 $2^n-1$
符号位
- 存放signed类型的存储单元中,左边第一位表示符号位。如果该位为0,表示该整数是一个正数;如果该位为1,表示该整数是一个负数
- 一个32位的整型变量,除去左边第一位符号位,剩下表示值的只有31个比特位
- 事实上计算机是用补码的形式来存放整数的值
- 正数的补码三该数的二进制形式
- 负数的补码需要通过以下几步获得:
- 先取得该数的绝对值
- 再将第1步的值按位取反
- 最后将第2步的值加1
数据类型 | 字节 | 取值范围 |
---|---|---|
char | 1 | -128~127 |
unsigned char | 1 | 0~255 |
short | 2 | -32768~32767 |
unsigned short | 2 | 0~65535 |
int | 4 | -2147483648~2147483647 |
unsigned int | 4 | 0~4294967295 |
long | 4 | -2147483648~2147483647 |
unsigned long | 4 | 0~4294967295 |
long long | 8 | -9223372036854775808~9223372035854775807 |
unsigned long long | 8 | 0~18446744073709551615 |
float | 4 | $1.1754910^{-38}~3.4028210^{38}$ |
double | 8 | $2.2250710^{-308}~1.7976910^{308}$ |
long double | 12 | $2.2250710^{-308}~1.7976910^{308}$ |
字符和字符串
ASCII编码表
数据类型 | 字节数 | 取值范围 |
---|---|---|
signed char | 1 | -128~127 |
unsigned char | 1 | 0~255 |
short | 2 | -32768~32767 |
unsigned short | 2 | 0~65535 |
int | 4 | -2147483648~2147483647 |
unsigned int | 4 | 0~4294967295 |
long | 4 | -2147483648~2147483647 |
unsigned long | 4 | 0~4294967295 |
long long | 8 | -9223372036854775808~9223372036854775807 |
unsigned long long | 8 | 0~18446744073709551615 |
字符串一般不会默认unsigned
// 声明字符串:
char name[5];
// 给字符串赋值:
name[0] = 'F';
name[1] = 'i';
name[2] = 's';
name[3] = 'h';
name[4] = 'C';
// 定义字符串:
char name[5] = {'F','i','s','h','C'};
类型转换
小坑位数据会转变为大坑位数据
#include <stdio.h>
int main()
{
printf("整型输出:%d\n",1+(int)1.8);// 类型强制转换
printf("浮点型输出:%f\n",1+2.0);
return 0;
}
运算符
算术运算符
C语言通过提供运算符来支持我们对数据进行处理
算术运算府
运算符 | 名称 | 例子 | 结果 |
---|---|---|---|
+ | 加法运算符(双目) | 5+3 | 8 |
- | 减法运算符(双目) | 5-3 | 2 |
* | 乘法运算符(双目) | 5*3 | 15 |
/ | 除法运算符(双目) | 5/3 | 1 |
% | 求余运算符(双目) | 5%3 | 2 |
+ | 正号运算符(单目) | +5 | 5 |
- | 负号运算符(单目) | -5 | -5 |
%不能将浮点数进行取余
目
表达式
-
用运算符和括号将操作数连接起来的式子,我们称之为表达式
1+1; 'a'+'b'; a+b; a+'b'+pow(a,b)*3/4+5;
运算符存在怕优先级
关系运算符
-
使用关系运算符来比较两个数的大小关系:
优先级相同(高)
<
(小于)< =
(小于或等于)>
(大于)优先级相同(低)
==
(等于)!=
(不等于)
关系表达式
-
用关系运算符将两边的变量、数据或表达式连接起来,称之为关系表达式:
1<2; a<b; a<=1+b; 'a'+'b'<='c'; (a=3)>(b=5);// 只会返回一个布尔值
-
关系表达式得到的值是一个逻辑值,即真或假,在C语言的逻辑运算中,用数字1表示真,用数字0表示假
逻辑运算符
运算符 | 含义 | 优先级 | 举例 |
---|---|---|---|
! |
逻辑非 | 高 | !a |
&& |
逻辑与 | 中 | a&&b |
` | ` | 逻辑或 |
逻辑与,参与的所有表达式,结果全部为真,才为真,只要有一个为假,就为假
逻辑或,参与的所有表达式中,只有一个结果为真,结果就为真,所有的都为假,才会为假
逻辑表达式
用逻辑运算符将两边的变量、数据或表达式连接起来,称之为逻辑表达式
短路求值
- 短路求值又称最小化求值,是一种逻辑运算符的求值策略。只有当第一个运算数的值无法确定逻辑运算的结果时,才对第二个运算数进行求值
- C语言对于逻辑与和逻辑或采用短路求值的方式
位运算符
运算符 | 功能 |
---|---|
& | 与 |
| | 或 |
^ | 异或 |
~ | 取反 |
» | 左移 |
« | 右移 |
赋值运算符
运算符 | 功能 |
---|---|
= | 赋值 |
+= | 加法且赋值 |
-= | 减法且赋值 |
*= | 乘法且赋值 |
/= | 除法且赋值 |
%= | 取余且赋值 |
»= | 左移且赋值 |
«= | 右移且赋值 |
&= | 按位与且赋值 |
|= | 按位或且赋值 |
^= | 按位异或且赋值 |
int a;
a = 5;
赋值运算符的左边必须是一个
lvalue
,变量名就是lvalue
复合的赋值运算符
int a;
a+=1;
a-=1;
a*=1;
a/=1;
自增自减运算符
int a;
a++;
++a;
a--;
--a;
其他运算符
sizeof运算符
sizeof
运算符
sizeof
运算符用于获得数据类型或表达式的长度
sizeof(object); //sizeof(对象);
sizeof(type_name); // sizeof(类型);
sizeof object; // sizeof 对象
条件运算符
- 语法:
exp1?exp2:exp3;
exp1
是条件表达式- 如果结果为真,返回
exp2
- 如果结果为假,返回
exp3
真左假右
逗号运算符
- 语法:表达式1,表达式2,……,表达式n
- 逗号表达式的运算过程为从左往右逐个计算表达式
- 逗号表达式作为一个整体,它的值为最后一个表达式(也即表达式n)的值
- a = (b = 3, (c = b + 4 ) + 5)
- 先将变量b赋值为3
- 然后变量c赋值为b+4的和,也就是7
- 接下来把c的值加上5
- 最后赋值给变量a,得到变量a的值是12
运算符优先级
优先级 | 运算符 | 结合律 |
---|---|---|
1 | 后缀运算符:[] () · -> ++ –(类型名称){列表} | 从左到右 |
2 | 一元运算符:++ – ! ~ + - * & sizeof_Alignof | 从右到左 |
3 | 类型转换运算符:(类型名称) | 从右到左 |
4 | 乘除法运算符:* / % | 从左到右 |
5 | 加减法运算符:+ - | 从左到右 |
6 | 移位运算符:« » | 从左到右 |
7 | 关系运算符:«= »= | 从左到右 |
8 | 相等运算符:== != | 从左到右 |
9 | 位运算符 AND:& | 从左到右 |
10 | 位运算符 XOR:^ | 从左到右 |
11 | 位运算符 OR:| | 从左到右 |
12 | 逻辑运算符 AND:&& | 从左到右 |
13 | 逻辑运算符 OR:|| | 从左到右 |
14 | 条件运算符:?: | 从右到左 |
15 | 赋值运算符: = += -= *= /= %= &= ^= |= «= »= | 从右到左 |
16 | 逗号运算符:, | 从左到右 |
逻辑结构
C语言中,包括三种执行流程
- 顺序结构,所谓的顺序结构呢,就是从上往下顺序的执行
- 选择结构,就是给出一个条件,如果条件符合,去哪里执行,不符合,又去哪里执行
- 循环结构,循环结构呢,就是重复执行某一段代码
分支结构
if语句
// if 语句(1)
if(表达式)
{
......// 逻辑值为真所执行的语句、程序块
}
// if 语句(2)
if(表达式)
{
......// 逻辑值为真所执行的语句、程序块
}
else
{
......// 逻辑值为假所执行的语句、程序块
}
// if 语句(3)
if(表达式1){......}
else if(表达式2){......}
else if(表达式3){......}
.
.
.
else if(表达式n){......}
else{......}
switch语句
break语句
switch(表达式)
{
case 常量表达式1:语句或程序块1;break;
case 常量表达式2:语句或程序块2;break;
......
case 常量表达式n:语句或程序块n;break;
default:语句或程序块n+1;break;
}
分支结构的嵌套
根据流程图写代码
悬挂else问题:else
会匹配最近的if
解决:{}
循环结构
while语句
// while语句 入口条件循环
while(i<=100)
{
sum = sum +i;
i= i + 1;
}
// do...while语句 出口条件循环
do{
sum = sum + i;
i = i + 1;
}
while(i<=100);
for循环
for(表达式1;表达式2;表达式3){
循环体
}
三个表达式用分号隔开,其中:
- 表达式1是循环初始化表达式
- 表达式2是循环条件表达式
- 表达式3是循环调整表达式
灵活的for语句
- 表达式1,表达式2和表达式3可以按照需要进行省略(但分号不能省)
- 表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式(即用逗号分隔多个表达式)
- C99允许在for语句的表达式1中定义变量
循环嵌套
先执行内部循环再执行外部循环
跳出循环
break语言
跳出循环
continue语言
跳出本轮循环
只能作用于一层循环
预处理
宏
宏(Macro)是预处理命令的一种,它允许用一个标识符来表示一个字符串。
define
#define nNum 15
#define ADD (a+b)
#define MAX(a,b) ((a>b)?(a):(b))
undef
取消宏处理
条件编译
#ifdef RKVIR
printf("this is def");
#else
printf("this is else");
#endif
#define SYS 2
#if SYS == 1
printf("1");
#elif SYS == 2
printf("2");
#endif
标准库
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
C的标准库
Header File | Content |
---|---|
stdio.h |
输入和输出 |
stdlib.h |
最常用的一些系统函数 |
string.h |
字符串处理 |
math.h |
数学函数 |
ctype.h |
字符类测试 |
time.h |
时间和日期 |
stdarg.h |
可变参数列表 |
signal.h |
信号 |
assert.h |
断言 |
setjmp.h |
非局部跳转 |
errno.h |
定义错误代码 |
stddef.h |
一些常数、类型和变量 |
locale.h |
本土化 |
float.h |
浮点数运算 |
limits.h |
定义整数数据类型的取值范围 |
补充
go to语句
类似于汇编语言的JMP
- 语法:goto标签;
#include <stdio.h>
int main()
{
int nNum = 0;
loop:
printf("%d\n", nNum);
nNum++;
goto loop;
return 0;
}
尽量永远不要用到
不建议使用
typedef
定义类型的别名
typedef int uint32;
typedef DATEBASE_CLASS_ONE DCO;