C语言基础
空白字符
空格 换行 制表符 TAB
空白字符只起到分隔作用,不充当语法成分
注释
// 单行注释
/* */ 多行注释
解释代码,说明变量作用或算法说明
测试代码,方便恢复
关键字和标识符
关键字:C语言语法规定,有固定含义与用途
大小写敏感:INT非关键字
标识符:用户自定义单词,给变量和函数取名字
规范:
标识符不能与关键字重复
大小写敏感
只包含数字、字母和下划线
开头不能是数字
常量
字面值常量
| 整数 | 值 |
|---|---|
| 整数 | 1234 |
| 浮点数 | 3.14 |
| 字符 | c |
| 字符串 | hello |
符号常量
使用宏定义实现符号常量
在预处理阶段做文本替换,但不会执行编译检查
#define R 4#define R 3+1两者不等,如果出现表达式需要加上括号
#define R (3+1)变量
一块有名字关联的内存空间
#include <stdio.h>
int main(){
int i;
printf("sizeof(i) = %d\n",sizeof(i));
double d1;
printf("sizeof(d1) = %d\n",sizeof(d1));
return 0;
}变量的初始化和赋值
初始化:在创建变量时赋予初始值
赋值:用新的值取代原来内存的里面的内容
数据类型
基本数据类型
整数
char 同时也是字符类型
short
int
long
无符号整数 unsigned
浮点数
单精度 float
双精度 double
整数类型
| 进制 | 数值 |
|---|---|
| 十六进制 | 0x1234 |
| 十进制 | 1234 |
| 八进制 | 01234 |
有符号整数
| 类型 | 字节 | 范围 |
|---|---|---|
| char | 1 | -28~28-1 |
| short | 2 | |
| int | 4 | |
| long | 4 | |
| long long | 8 |
N个bit的有符号整数:-2N~2N-1
整数溢出问题
int i = 0x7fffffff ;
i = i + 1 ;正数做运算时算出的结果变成了负数
无符号整数
unsigned + 有符号类型 范围: 0~2N-1
任何数据类型均会溢出
浮点数
| 类型 | 字节 | 有效位数 |
|---|---|---|
| float | 4 | 6 |
| double | 8 | 15 |
整数是精确的,浮点数是近似值,有误差
两个浮点数绝对值相差很大,可能会出现精度丢失问题
字符类型
字符只能显示一位
| 转移字符 | 作用 |
|---|---|
| \n | 换行 |
| \r | 回车 |
| \b | 退一格 |
| \t | 制表符 |
| \\ | \ |
char ch = 'a';
printf("%d",a);
=>97编码规则:记录各种数值与字符之间的对应关系 ---> ASCII
字符 ‘ 0 ’ = 数值 48
a = A + 32 大写字母与小写字母相差32
一个整数字面值常量优先是int -> unsigned int -> long long ->unsigned long long
任何浮点数字面值常量均为 double 类型
float 1/2 = 0
float 1.0/2 = 0.5long long ll;
ll = 131072 * 131072 => int * int //中间过程值精度损失(溢出)导致结果错误
ll = (long long)131072 * 131072输入和输出
stdin 标准输入缓存区 --> scanf getchar fgets
stdout 标准输出缓冲区 --> printf puts
#include <stdio.h>
int main(){
int i; // 用于存放从stdin过来的数据
int ret = scanf("%d",&i);
// %d是控制符,用于说明将要接收的数据类型为整数
// &i,将数据存入 i 的地址中
printf("ret = %d,i = %d\n",ret,i);
}准备变量 --- 数据的目的地
scanf的两类参数 第一类参数:字符串,用于描述数据的格式;第二类参数用于存放数据地址,&
scanf的返回值是读取成功的变量个数
如果返回值和%符号个数相等则成功
如果返回值小于%符号个数 则失败
如果返回值为-1,则是特殊情况EOF
stdin 缓冲区的本质是一个队列
scanf %c 不会忽略空白字符
int i ;
char ch;
scanf("%d%c",&i,&ch);
printf("i=%d,ch = %c\n",i,ch);一般的使用场景,绝大多数情况下 scanf的格式字符串里面,只有%控制符,偶尔会在%c前面加空格
getchar 等价于 scanf %c ,也不会忽略空白字符
stdout 是一种行缓冲,当数据中有换行符的时候,就会刷在屏幕上
char name[] = "duskwind";
int age = 30;
char addr[] = "njupt";
printf("name:%s,age:%d,address:%s",name,age,addr);| 占位符 | 含义 |
|---|---|
| %c | 字符 |
| %d | 十进制 |
| %o | 八进制 |
| %x | 16进制 |
| %f | 浮点数 |
| %u | 无符号整数 |
| %lld | long long |
| %ld | long |
| %s | 字符串 |
设置数据的宽度
%和d/s/c/f 之间可以添加整数,用来描述最小宽度
整数前面加负号,可以实现左对齐
整数前面加零号,可以让不足宽度的数据填充0
浮点数设置
double f = 3.141592653579;
printf("f = %20.15f", f);
// 即输出最小宽度是20,小数点后有15位puts 打印一行
puts(str) 等价于 printf("%s\n",str)运算符
算术运算符
关系运算符
逻辑运算符
位运算符
其他:条件运算符 逗号运算符
算符运算符
#include <stdio.h>
int main(){
int a = 10,b = 3;
printf("a + b = %f\n", a + b);
printf("a - b = %f\n", a - b);
printf("a * b = %f\n", a * b);
printf("a / b = %f\n", a / b); //取余运算符的操作数必须是整数
return 0;
}#include <stdio.h>
int main(){
int a = 1,b = 2,c = 3;
printf("output = %d\n",a + b * c);
return 0;
}优先级 * / % 高于 + -
相同优先级按照从左向右的顺序
关系运算符
在C语言中,数据机器数0为假,非0为真
#include <stdio.h>
int main(){
int condition = 1;
if (condition)
printf("true\n");
else
printf("false\n");
return 0;
}| 关系运算符 | |
|---|---|
| 相等 | == |
| 不相等 | != |
| 大小关系 | < <= > >= |
满足条件就返回1,不满足返回0
#include <stdio.h>
int main(){
int a = 1,b = 2,c = 3;
printf("a < b <c is %d\n",a < b <c);
return 0;
}// output = 1注意逻辑:不是看数学上:a < b < c
而是先执行 a < b,然后再执行a < b的结果是否小于c
判断大小的运算符比判断相等运算符优先级高
#include <stdio.h>
int main(){
int a = 1,b = 2,c = 1;
printf("a == b < c is %d\n",a == b <c); //0
printf("(a == b) < c is %d\n",(a == b) <c);//1
return 0;
}// output = 1逻辑运算符
对布尔表达式(返回真或假) 做运算
| 左值 | 右值 | 逻辑与 | 逻辑或 | 逻辑非(左值) |
|---|---|---|---|---|
| L | R | && | | | |
| 1 | 1 | 1 | 1 | 0 |
| 1 | 0 | 0 | 1 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 0 | 0 | 0 | 0 | 1 |
优先级
单目运算符 高于 算术 高于 关系 高于 逻辑
短路操作
逻辑与的左操作数为假,可以不执行右操作数
逻辑或的做操作数为真,可以不执行右操作数
#include <stdio.h>
int main(){
int i = 1, j = 1;
i == j || (j = 2 );
printf("j = %d",j);
return 0;
}当表达式存在 && 或者 || ,应当先执行左边看是否触发短路,再考虑执行右边
赋值运算符
L = R (优先级比较低)
L必须代表一片内存空间,该内存空间可以被修改
#include <stdio.h>
int main(){
int i = 1;// 非赋值,是初始化
i = 3 + 4;
i = i + 1; // i在左边表示访问地址,在右边表示获取值
++i;
x = y = 1; // 右结合
return 0;
}条件运算符(三目运算符)
x :y ? z
判断 x ,若为真,返回 y,否则返回 z
一般而言使用if else
逗号运算符(优先级最低)
A,B 先执行A在执行B,最后返回B