文档版本 | 更新时间 | 更新内容 |
---|---|---|
v1.0 | 2020-09-13 | 初稿完成 |
v1.1 | 2020-09-16 | 添加static关键字部分 |
文章目录
- 一、数据类型
- 1. 数据类型关键字
- 2. 可移植数据类型
- 3. 整数溢出问题
- 二、变量与常量
- 1. 五种常见变量
- 2. 常量的两种定义方式
- 三、转义字符
- 四、浮点数
- 1. 科学计数法
- 2. 浮点数的精度
- 3. 浮点数的存储所带来的问题
- 五、输入输出
- 1. 转换说明符
- 2. printf的用法
- 2.1. 基本用法
- 2.2. printf的转换说明修饰符
- 3. scanf的用法
- 3.1. scanf的基本用法
- 3.2. scanf的输入分割
- 4. *修饰符
- 六、运算符
- 1. 常用运算符
- 2. C语言中的真和假
- 3. 运算符优先级(非常重要)
- 4. 其它运算符
- 七、流程控制
- if..else分支结构
- switch...case分支结构
- while循环结构
- for循环结构
- do...while循环结构
- 八、函数
- 1. 函数声明
- 2. 函数定义
- 九、数组
- 1. 数组的作用
- 2. 一维数组
- 3. 二维数组
- 4. 多维数组的本质
- 十、static关键字
- 1. static静态变量
- 2. static静态函数
一、数据类型
1. 数据类型关键字
数据类型 | 占用字节 | 范围 |
---|---|---|
char | 1 | -128 - 127 |
unsigned char | 1 | 0 - 255 |
short | 2 | |
unsigned short | 2 | |
int | 4 | |
unsigned int | 4 | |
long | 4 | |
unsigned long | 4 | |
long long(C99加入) | 8 | |
unsigned long long(C99加入) | 8 | |
float | 4 | |
double | 8 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20/** * CPU:64bit * OS:Windows10 * IDE:Clion * Compiler:MinGW-64 */ #include <stdio.h> int main() { printf("char:%drn", sizeof(char)); printf("short:%drn", sizeof(short)); printf("int:%drn", sizeof(int)); printf("long:%drn", sizeof(long)); printf("long long:%drn", sizeof(long long)); printf("float:%drn", sizeof(float)); printf("double:%drn", sizeof(double)); return 0; }
运行结果为:
1
2
3
4
5
6
7
8char:1 short:2 int:4 long:4 long long:8 float:4 double:8
2. 可移植数据类型
int的长度会跟随CPU的不同而发生变化,比如:
- 16位CPU中:int默认两个字节,16位(int规定的最小值)
- 32位CPU中:int默认四个字节,32位;
所以通常情况下使用C头文件<stdint.h>
中提供的数据类型:
- int8_t
- uint8_t
- int16_t
- uint16_t
- int32_t
- uint32_t
- int64_t
- uint64_t
同时,该头文件提供了数据类型的最大最小值宏定义,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/* 7.18.2.1 Limits of exact-width integer types */ #define INT8_MIN (-128) #define INT16_MIN (-32768) #define INT32_MIN (-2147483647 - 1) #define INT64_MIN (-9223372036854775807LL - 1) #define INT8_MAX 127 #define INT16_MAX 32767 #define INT32_MAX 2147483647 #define INT64_MAX 9223372036854775807LL #define UINT8_MAX 255 #define UINT16_MAX 65535 #define UINT32_MAX 0xffffffffU /* 4294967295U */ #define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
3. 整数溢出问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/** * CPU:64bit * OS:Windows10 * IDE:Clion * Compiler:MinGW-64 */ #include <stdio.h> #include <stdint.h> int main() { int8_t a = -128, b = 127; uint8_t c = 0, d = 255; a = a - 1; b = b + 1; c = c - 1; d = d + 1; printf("a = %d, b = %drn", a, b); printf("c = %d, d = %drn", c, d); return 0; }
运行结果如下:
1
2
3a = 127, b = -128 c = 255, d = 0
原因:
- 无符号整数溢出:最高位进位,因为存储空间大小限制,超出的部分直接舍弃,所以会从0开始重新计数。
- 有符号整数溢出:数据位进位,导致符号位变为1,数据位清零,所以会从对应的最小的负数开始重新计数。
详细说明参考博文:整数在计算机中的存储
二、变量与常量
- 变量:在程序运行过程中会改变,本质就是内存中的一段存储空间;
- 常量:运行过程值不会改变;
1. 五种常见变量
① 局部变量:在函数内部定义,函数结束后变量自动销毁;
② 全局变量:在函数外部定义,整个文件内部都可以使用该变量,程序结束后销毁;
③ 外部变量:使用extern修饰,表示该变量在其它文件中定义为全局变量;
④ 静态变量:使用static修饰,表示该变量在定存中只有一份定义;
⑤ 易变变量:使用volatile修饰,表示该变量是易变的,防止编译器优化;
2. 常量的两种定义方式
常量有两种:
① 使用const修饰符,作为只读变量:
1
2const double pi = 3.1415926;
② 使用字面值:
1
2#define PI 3.1415926
字面值的数据类型会被编译器自动识别:整数默认int,浮点数默认double,如果存不下则自动寻找更大的类型存储。
可以在数值后面加后缀,显示指出要使用的数据类型:
U或u
:unsignedL或l
:long int 或者Long doubleLL或ll
:long longF或f
:float
三、转义字符
四、浮点数
1. 科学计数法
2. 浮点数的精度
- float类型的精度:能表示小数点后6位;
- doubel类型的精度:能表示小数点后10位;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21/** * CPU:64bit * OS:Windows10 * IDE:Clion * Compiler:MinGW-64 */ #include <stdio.h> #include <stdint.h> int main() { float a, b; b = 2.0e20 + 1.0; a = b - 2.0e20; printf("a = %frn", a); return 0; }
运行结果为:
1
2a = 4008175468544.000000
因为float只能存储小数点后6位的精度,所以肯定错误。
如果将2.0e20改为2.0e4,则运行结果为:
1
2a = 1.000000
浮点数的值:2.0e4=20000,2.0e-4=0.0002
3. 浮点数的存储所带来的问题
因为浮点数不能精准的存储,所以需要在编程时注意。
eg:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18/** * CPU:64bit * OS:Windows10 * IDE:Clion * Compiler:MinGW-64 */ #include <stdio.h> #include <stdint.h> int main() { float a = 99.9; printf("a = %frn", a); return 0; }
运行结果为:
1
2a = 99.900002
五、输入输出
1. 转换说明符
常用的一些占位符如下表:
占位符 | 说明 |
---|---|
%d | int |
%ld | long |
%c | char |
%f | float |
%lf | double |
%x | int、short、long |
%o | int、short、long |
%s | 字符串 |
%e或者%E | 使用e计数法输出浮点数 |
%x或者%X | 无符号十六进制输出整数 |
%% | 打印一个百分号 |
2. printf的用法
2.1. 基本用法
头文件:
1
2#include <stdio.h>
用法:
1
2
3
4printf("字符串"); printf("字符串 占位符1 占位符2", 输出参数1, 输出参数2);
2.2. printf的转换说明修饰符
在%
和转换字符
之间插入修饰符可修饰基本的转换说明。
其中可用标记如下表:
3. scanf的用法
scanf的作用:将用户从键盘输入的字符串转换为字符、字符串、整数、浮点数。
3.1. scanf的基本用法
特别注意!输入参数是变量的地址!
头文件:
1
2#include <stdio.h>
1
2
3
4
5scanf("占位符", 输入参数); //这种用法,在输入的时候必须将非占位符也输入 scanf("非占位符 占位符", 输入参数);
3.2. scanf的输入分割
scanf函数使用空白(换行符、制表符、空格)把输入分成多个字段,在依次把转换说明和字段匹配时跳过空白。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22/** * CPU:64bit * OS:Windows10 * IDE:Clion * Compiler:MinGW-64 */ #include <stdio.h> int main() { int a; float b; char c[20]; scanf("%d%f%s", &a,&b, c); printf("a is %d, b is %.2f,c is %srn", a, b, c); return 0; }
运行结果如下:
1
2
3
4
51234124 1.23452 hello a is 1234124, b is 1.23,c is hello
4. *修饰符
① 在printf中,*修饰符用来代替字段宽度,由变量指定。
② 在scanf中,*修饰符表示跳过这个转换说明符。
六、运算符
1. 常用运算符
① 算术运算符:
+、-、*、/
C语言中,两个整数之间用
/
运算,结果也是整数。
② 关系运算符:
、>=、<、<=、!=、==
③ 逻辑运算符:
!、&&、||
④ 赋值运算符:
=、+=、-=、/=、*=
2. C语言中的真和假
- 假:0;
- 真:非0,除0之外都是真,一般用1表示;
3. 运算符优先级(非常重要)
算术 > 关系 > 逻辑 > 赋值
4. 其它运算符
- sizeof运算符:返回结果是size_t类型(无符号整型,由编译器使用typedef替换为基本数据类型,在stddef.h中定义,包含在stdio.h里)
- 求模运算符:%(只能用于整数、不能用于浮点数)
- 自增运算符:++(分为前缀和后缀)
- 自减运算符:–(分为前缀和后缀)
- 三目运算符:?:
- 位运算符:&、|、~、^、<<、>>
七、流程控制
if…else分支结构
switch…case分支结构
特别注意!case之后的标号只允许字面常量,且是整型。(变量、const只读变量、浮点数都是错误的)。
while循环结构
for循环结构
do…while循环结构
八、函数
函数是C语言的基本单位。
1. 函数声明
1
2函数返回值类型 函数名(函数参数列表);
2. 函数定义
1
2
3
4
5
6
7函数返回值类型 函数名(函数参数列表) { 函数主体; return 返回值; }
九、数组
1. 数组的作用
解决同类型数据的存储问题。
2. 一维数组
① 定义数组:
1
2<数据类型> <数组名>[数组中元素个数];
② 初始化数组
完全初始化:
1
2int a[5] = {1,2,3,4,5};
不完全初始化,未被初始化的元素为0:
1
2int a[5] = {1,2,3};
不初始化,所有元素都是垃圾值:
1
2int a[5];
清零:
1
2
3//原理:第一个元素初始化为0,属于不完全初始化,所以全部为0 int a[5] = {0};
eg:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/** * CPU:64bit * OS:Windows10 * IDE:Clion * Compiler:MinGW-64 */ #include <stdio.h> #include <stdint.h> int main() { int a[5]; int i; for (i = 0; i < 5; i++) { printf("%d ", a[i]); } printf("rn"); return 0; }
运行结果为:
1
28 0 73 0 1647344
③ 数组可以进行的操作:
- 遍历
- 赋值
- 排序
- 求最大值/最小值
- 倒置
- 查找
- 插入
- 删除
3. 二维数组
① 定义:
1
2
3//一个3行4列的二维数组 int a[3][4];
② 初始化
整体赋值:
1
2int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
整体赋值的另外一种写法:
1
2
3
4
5
6
7int a[3][4] = { {1,2,3}, {4,5,6}, {7,8,9}, {10,11,12} };
③ 访问(按下标):
1
2a[i][j]
④ 二维数组的操作:
- 排序
- 矩阵操作
4. 多维数组的本质
物理内存是线性连续的,所以多维数组本质并不存在。
3行4列的二维数组,本质上是3个元素一维数组,只不过每个元素也是含有4个小元素的一维数组。
十、static关键字
static关键字表示静态的,可以用来修改变量和函数。
1. static静态变量
static关键字修饰变量后,表示该变量是静态的,无论定义多少次,在内存中只有一份。
比如下面的示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <stdio.h> int test(void) { int ret; static int id = 0; ret = id++; return ret; } int main() { int id; for (int i = 0; i < 10; i++) { id = test(); printf("id = %drn", id); } return 0; }
运行结果为:
1
2
3
4
5
6
7
8
9
10
11id = 0 id = 1 id = 2 id = 3 id = 4 id = 5 id = 6 id = 7 id = 8 id = 9
2. static静态函数
static修饰静态函数,表示此函数只能在本文件中使用。
最后
以上就是唠叨哈密瓜最近收集整理的关于C语言集锦 | 01 - C基础语法(数据类型、输入输出、运算符、流程控制、函数、数组、static关键字)一、数据类型二、变量与常量三、转义字符四、浮点数五、输入输出六、运算符七、流程控制八、函数九、数组十、static关键字的全部内容,更多相关C语言集锦内容请搜索靠谱客的其他文章。
发表评论 取消回复