文章目录
C程序设计语言符号关键字,数据类型,输入输出与基本程序结构
关键字
系统预先定义好的,有特定含义的,都是小写,不能重新定义(32个关键字!!)
类型 | 关键字 |
---|---|
数据类型 | char、short、int、long、float、double、struct、union、enum、void |
控制语句 | if、else、while、switch、case、default、break、continue、for、do、goto |
存储类型 | auto、static、extern、register |
其他 | return返回函数,const只读,signed有符号数,unsigned无符号数,sizeof求所占内存空间的大小(sizeof(数据类型)、sizeof(变量名)),typedef给已有的数据类型起别名,volatile防止编译器优化 |
标识符
程序员自己去定义的,一般用来定义变量名,函数名,类型名
要求:
1.不能和关键字重名。
2.数字、字母、下划线、组成。
3.第一个不能为数字。
转义字符
\a //响铃
\b //退格
\f //换页
\n //换行
\r //回车
\t //水平制表
\v //垂直制表
\\ //反斜杠字符
\? //问号字符
\' //单引号字符
\" //双引号字符
\0 //空字符,在每一个字符串末尾存在
\ddd //三位八进制
\xhh //二位十六进制
常量
常量类型 | 例子 |
---|---|
字符常量 | ‘a’,‘A’ |
整型常量 | 二进制1010,八进制076十进制99 -5,十六进制:0xaf7c(默认情况下整形常量有符号),无符号的int整型数66U,无符号的长整型66UL |
浮点型常量 | 小数1.45 0.00001 10000(浮点型常量包含整形常量)指数形式1e-4 1e+4 |
字符串常量 | “hello”,“world”(字符串最后有一个\0作为结束符,但不显示) |
标识常量(宏) | #define 宏名 表达式 |
标识常量
书写规范:
1.宏名一般用大写,小写也可以,但是为了和普通的变量区分开,用大写。
2.宏后面没有分号。
宏的特性:
宏只是一个单纯的替换。
例子:
#include<stdio.h>
#define SUM(a,b) a+b
int main(){
int a=1,b=3,c=5;
printf("%d",SUM(a,b)*c);
return 0;
}
最终计算结果是16。因为宏只是一个单纯的替换,并不会提高计算优先级,算式并不会变成"(1+3)*5=20"而依旧是"1+3*5=16"。
变量
意味着要开辟内存空间。
定义一个变量:存储类型+数据类型+变量名
register int a;
类型 | 名字 |
---|---|
存储类型 | auto static register extern |
数据类型 | char short int long float double |
局部变量定义在函数体内部,全局变量定义在函数体外部。
而变量初始化则意味着 在定义变量时就给变量赋值,若不初始化,全局变量默认为0,局部变量默认为一个随机数。
存储类型
内存空间分布:
类型 | 存储区域 |
---|---|
auto | 只能修饰局部变量,修饰的变量存储在栈区 |
extern | 只能修饰全局变量,修饰的变量存储在静态区 |
static | 既可以修饰全局变量,也可以修饰局部变量,修饰的变量存储在静态区。 |
register | 只能修饰局部变量,修饰的变量存储在寄存器中,若寄存器已满会存储在栈区 |
存储在静态区的变量被称作静态变量。
生命周期与作用域
生命周期指的是从开辟空间到释放空间的一段周期。作用域指的是变量有效的范围。
下面重点描述static修饰后的变量特性:
修饰变量类型 | 生命周期 | 作用域 |
---|---|---|
局部变量 | 延长生命周期从声明到函数后部大括号结束延长为整个程序结束 | 依旧是函数内部 |
全局变量 | 依旧是从声明到整个程序结束 | 只能在所定义的.c文件内使用 |
static其他特性:
1.如果局部变量没有初始化,则赋值0。
2.如果局部初始化了,那么只能初始化一次。
例子:
#include<stdio.h>
int main(){
int i;
for(i=1;i<10;i++){
static int a=0;
a++;
printf("%d",a);
}
return 0;
}
输出结果为123456789,变量a并没有在每次循环时重新赋值为0,而是延续上一次循环的数值。
数据类型转换
有强制数据类型转换和隐式类型数据转换两种。
强制数据转化是在程序设计中操作的。例如:
float a=1.1;
int b=0;
b=(int)a;
上面就是将浮点变量的转换为整型变量后赋值给整型变量b。
而隐式类型转化则为编译器自动转换的。
横向的不管有没有进行混合运算都会及逆行转换。
运算符
优先级口诀:单算移关与,异或逻条赋。
运算符类型 | 运算符 |
---|---|
单目运算符 | ++,– |
算术运算符 | +,-,*,/ |
位移运算符 | <<,>> |
关系运算符 | <,>,>=,<=,==,!= |
逻辑运算符 | &&,|| |
位运算符 | &,|,^,~ |
三目运算符 | 表达式1?表达式2:表达式3 |
逗号运算符 | 表达式1,表达式2,……,表达式n |
sizeof运算符 | sizeof(变量名)或sizeof(数据类型) |
赋值运算符 | = |
单目运算符
++或者是–在变量后面,则先赋值后运算。在变量前面则先运算再赋值。
关系运算符
典型错误:
#include<stdio.h>
int main(){
int i=1;
if(2<i<1){
printf("01");
}
else{
printf("02");
}
return 0;
}
以上输出结果是01,因为i先与2比较,结果是i不大于2,所以得到布尔值0(假),之后布尔值0再与1比较,得到结果是布尔值小于1,所以最后输出的是01。
正常书写这一关系判断语句应为:
2<i&&i<1
(但如上书写就需要注意逻辑运算符的截断法则,在下一节会提到)
还需要注意的是判断是否等于用的是“==”,而不是“=”。
逻辑运算符
与运算符&&:
表达式1&&表达式2&&...
截断法则:有一个表达式为假,则结果结果就为假;前一个表达式为假,后面表达式就不再进行运算。
或运算符||
表达式1||表达式2||...
截断法则:有一个表达式为真,则结果结果就为真;前一个表达式为真,后面表达式就不再进行运算。
三目运算符
表达式1?表达式2:表达式3
判断表达式1,是否成立,如果成立,就将表达式2的值作为整个表达式的值,否则,就将表达式3的值作为整个表达式的值。
逗号运算符
表达式1,表达式2,表达式3,...,表达式n
从左往右依次计算每个表达式的值,将表达式n的值作为整个表达式的值
逗号运算符的优先级是最低的,因此在使用的时候,要加上括号。
典型错误:
#include<stdio.h>
int main(){
int i=1;
printf("%d",(i++,i+5,i-2));
return 0;
}
以上输出结果是0,因为i+5并没有改变i的值,i经历过i++后是2,然后表达式3中i-2变为0。
位运算符
&可以将xx至xx位清零,例如将1101 1111的0至2位清零:
1101 1111
&1111 1100
=1101 1100
|运算符可以同理将xx至xx位赋值为1。
异或运算符是相同则为0,不同则为1。
位移运算符
位移对象<<位移n位参数
移动方向 | 对象变量类型 | 操作 |
---|---|---|
左移<< | unsigned | 高位丢弃,低位补0 |
左移<< | signed | 符号位不变,高位丢弃,低位补0 |
右移>> | unsigned | 低位丢弃,高位补0 |
右移>> | signed | 符号位不变,低位丢弃,高位补1 |
输入输出
输入:从键盘的数据移入到内存中。
输出:将内存中的数据打印到终端。
标准输入函数是scanf,标准输出函数是printf。字符输入函数是getchar,字符输出函数是putchar。
格式控制串
整型格式控制串
控制串 | 含义 |
---|---|
%d | 以整型形式进行输出 |
%#o | 以八进制形式进行输出 |
%#x | 以十六进制形式进行输出 |
%u | 以无符号整型进行输出 |
%hd | 以short类型进行输出 |
%ld | 以long类型进行输出 |
浮点控制串
控制串 | 含义 |
---|---|
%f | 单精度浮点类型 |
%lf | double类型 |
%g | 选择小数/指数较短的一种进行输出 |
%e | 以指数形式进行输出 |
%.nf | 保留小数点后n位进行输出 |
%m.nf | m:指定我们输出的域宽:当m大于0时,默认右对齐,m小于0,左对齐。当m的值大于数据的实际长度时,补空格,m小于数据的实际长度,原样输出 |
若不指定输出多少位小数则默认输出小数点后六位。
字符控制串
%c
scanf和printf
scanf("格式控制串",地址表); //地址表是&+变量名
printf("格式控制串",输出表);
scanf里如果格式控制串加了修饰语则输入时修饰语同样也需要加,典型比如空格。全部输入完成后以回车作为终端输入结束的标志。
在控制串中写一个抑制符%*c可以吃掉一个字符。
getchar和putchar
都会将键入的字符转换为ascii码。
程序基本结构
程序有三大基本结构:顺序结构,选择结构,循环结构。
其中顺序结构即按照语句的先后顺序去执行。以下会重点解释选择结构和循环结构。
break和continue
break是跳出离其最近的函数结构(因为有多重嵌套的情况);而continue以循环结构为例是跳出本次循环,执行下一次循环。
选择结构
单分支选择结构
if(表达式){
语句;
}
双分支选择结构
if(表达式){
语句;
}
else{
语句;
}
多分支选择结构
if型
if(表达式1){
语句1;
}
else if(表达式2){
语句2;
}
else if(表达式3){
语句3;
}
……
else if(表达式n){
语句n;
}
else{
语句n+1;
}
if-else if型先判断表达式的值是否成立,如果成立,就执行语句1,否则,执行语句2,一次类推。
switch型
Switch(表达式){
case 标号1:语句1;
case 标号2:语句2;
case 标号3:语句3;
……
case 标号n:语句n;
default:语句n+1;
}
switch case型表达式不能为浮点型,标号为常量。
当表达式等于标号时,执行当前标号及之后标号的语句,直到switch结构结束或者是break跳出switch结构。
循环结构
for循环
for(表达式1;表达式2;表达式3){
循环体;
}
表达式1:循环的初始条件。
表达式2:循环的终止条件。
表达式3:循环变量的变化。
先执行表达式1,再执行表达式2,如果表达式2为真,执行循环体,然后执行表达式3,去判断表达式2是否成立,如果成立则,继续执行循环体,否则,跳出。
省去表达式1则需要在循环体外提前赋值,省去表达式2则进入死循环,省去表达式3则需要在循环体内部对循环变量进行操作。
while循环
while(表达式){
循环体;
}
while(1)//死循环
若表达式成立则执行循环体,否则不执行。
do while循环
do{
循环体;
}while(表达式)
先执行循环体,然后判断表达式是否成立,若表达式成立则执行循环,否则跳出循环。
goto循环
标号
goto 标号
当执行到goto时自动跳转回标号处重新执行。