C语言基础知识整理合集
变量和类型
1B=8bit
1kB=1024B
1mB=1024kB
1GB=1024MB
1TB=1024GB
1PB=1024TB
- 先定义后使用
- 字母数字下划线,不能数字开头
# 整数类型
类型 | 存储大小 | 值范围 |
---|---|---|
char | 1 字节 | -128 到 127 或 0 到 255 |
unsigned char | 1 字节 | 0 到 255 |
signed char | 1 字节 | -128 到 127 |
int | 2 或 4 字节 | -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647 |
unsigned int | 2 或 4 字节 | 0 到 65,535 或 0 到 4,294,967,295 |
short | 2 字节 | -32,768 到 32,767 |
unsigned short | 2 字节 | 0 到 65,535 |
long | 4 字节 | -2,147,483,648 到 2,147,483,647 |
unsigned long | 4 字节 | 0 到 4,294,967,295 |
# 浮点数类型
类型 | 存储大小 | 值范围 | 精度 |
---|---|---|---|
float | 4 字节 | 1.2E-38 到 3.4E+38 | 6 位小数 |
double | 8 字节 | 2.3E-308 到 1.7E+308 15 | 位小数 |
long double | 16 字节 | 3.4E-4932 到 1.1E+4932 | 19 位小数 |
# 类型定义
变量是有地址中的一个值
和名字
构成的.
在定义中不允许连续赋值,如int a=b=c=5;是不合法的。
# 类型转换
(doubel)a
;
字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128~127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围是0~255(有些机器把char型当做unsighed char型对待, 取值范围总是0~255)。
- 浮点数赋给整型,该浮点数小数被舍去;
- 整数赋给浮点型,数值不变,但是被存储到相应的浮点型变量中; 强制类型转换的时候:
自动类型转换:char->int->double<-char
强制类型转换:char,short->unsigned->long->double<-float
不能逆序,会有信息损失,分数转成整数就会舍掉小数位,char类型数据转换为int类型数据遵循ASCII码中的对应值
看这里
int a=5;
double_a=(double) a;
#类型转换不会影响原来的值
# 字符&字符串
字符
定义字符用char
来定义(实质上是ascii的编码的int),所占空间和范围见上表,占位符使用%c
char q='a'
char x='x';
printf("%d,%c",x,x);
声明一个字符,但是我们用整型输出,就会输出它对应的ASCII码数字了,char只能存储一个字符,它的取值范围是:ASCII码字符 或者 -128~127的整数
WARNING
用''
单引号,切忌,千万不能用双引号,双引号是来表示字符串的。
字符串
c中没有string。c的字符串是以null'/0'
结尾的一维字符数组,字符数量会比实际显示的字符数多1,可以简写为char yy[] = "Hello";
char xx[4]={'x','y','z','\0'};
char yy[]="hello";
printf("%s,%s",xx,yy);
c基本的几个函数(等后面c++里还会变)
序号 | 函数 | 目的 |
---|---|---|
1 | strcpy(s1, s2); | 复制字符串 s2 到字符串 s1。 |
2 | strcat(s1, s2); | 连接字符串 s2 到字符串 s1 的末尾。 |
3 | strlen(s1); | 返回字符串 s1 的长度。 |
4 | strcmp(s1, s2); | 如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。 |
5 | strchr(s1, ch); | 返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。 |
6 | strstr(s1, s2); | 返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。 |
----from 菜鸟教程
# 枚举enum
enum 名字 {e1,e2,e3...} e;
这样就定义了一个枚举e(也可以先不定义e,后面enum 名字 e),第一个元素e1默认为0,后续元素逐个+1,可以自己定义,如e3=5那么元素变为0,1,5,6...
WARNING
枚举被定义int或unsigned int,不连续的枚举无法遍历
留坑
# 常量
# define
#define X 3
定义了X为3,利用宏定义,不能改变,不做计算,不做表达式求解
- define宏是在预处理阶段展开。
- define宏没有类型,不做任何类型检查,仅仅是展开
- define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。
冷知识
宏定义不分配内存,变量定义分配内存
比如说C语言标准规定编译器至少支持宏的名字有63个字符(多的话意义不能保证),至少支持同时定义4095个宏,函数形的宏最多可能有127个参数
# const
const 变量类型 X=3
使用const定义了X为3
- const常量是编译运行阶段使用。
- const常量有具体的类型,在编译阶段会执行类型检查
- const常量会在内存中分配(可以是堆中也可以是栈中) const 可以节省空间,避免不必要的内存分配看代码
#define PI 3.14159 //常量宏
const doulbe Pi=3.14159; //此时并未将Pi放入ROM中
double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存!
WARNING
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝(因为是全局的只读变量,存在静态区),而 #define定义的常量在内存中有若干个拷贝。
编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
一些规则
- 有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。
- 在C++ 程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。
- 需对外公开的常量放在头文件中,不对外公开的常量放在定义文件头部,可以把不同模块的常量集中放在一个公共头文件中
- 如果某一常量与其它常量密切相关,应在定义中包含这种关系,而不应给出一些孤立的值。
WARNING
const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其const数据成员的值可以不同,应该用类中的枚举常量来实现
# 输入输出
# IO含树
scanf和printf
scanf("占位符1,占位符2",变量地址1,变量地址2,...);
控制台输入要和这个一样1,2
printf(“格式控制字符串”, 输出表列)
printf和puts两者都属于stdio.h这个头文件,都能输出字符串
puts()在输出字符串时会将'\0'自动转换成'\n'进行输出.
# 占位符
格式字符有d,o,x,u,c,s,f,e,g等。
类型 | 作用 |
---|---|
%d | 整型输出 |
%ld | 长整型输出, |
%o | 以八进制数形式输出整数, |
%x | 以十六进制数形式输出整数,或输出字符串的地址。 |
%u | 以十进制数输出unsigned型数据(无符号数)。 |
%c | 用来输出一个字符, |
%s | 用来输出一个字符串, |
%f | 用来输出实数,以小数形式输出,默认情况下保留小数点6位。 |
%.100f | 用来输出实数,保留小数点100位。 |
%e | 以指数形式输出实数, |
%g | 根据大小自动选f格式或e格式,且不输出无意义的零。 |
WARNING
%d与%u有无符号的数值范围,也就是极限的值,不然数值打印出来会有误。
# 特殊符号
6个特殊符号
符号 | 意义 | ascii对应 |
---|---|---|
空格 | ' ' | \u0020 |
换页 | '\f' | |
换行 | '\n' | \u0010 |
回车 | '\r' | \u0013 |
水平制表符 | '\t' | \u0009 |
垂直制表符 | '\v' |
# 运算符
常见的我就不放了,注意%
是取余数
等级 | 运算符 |
---|---|
1 | ( ) |
2 | ! +(正号) -(负号) ++ -- |
3 | * / % |
4 | +(加) -(减) |
5 | < <= >= > |
6 | == != |
7 | && |
8 | ** |
9 | ?: |
10 | = += -= *= /= %= |
WARNING
注意:复合运算符中运算符和等号之间是不存在空格的。