头文件
stdio.h(=standard input output+head)
stdio.h=cstdio
变量
不能是c语言标识符
第一个字符必须字母或下划线
区分大小写
整型
int 绝对值在10^9范围以内
long long 超过以上
浮点型
float 单精度,6~7位有效精度
double 双精度 15~16位
%f是输出格式
碰到浮点都用double
字符型
小写字母比大写字母ASCII码大32
字符常量(单个字符)用单引号
转义字符:\n换行 \0空字符
字符串常量:只能用字符数组,双引号,%s是输出格式
char str2[25] = "so sad a story it is.";
注意不要把字符串常量赋给字符变量,即不要出现char c = "abcd"的写法
bool型要添加头文件stdbool.h
0,1代表false,true
a == b 也是判断条件
强制转换
如
double r = 12.56;
(int)r;
符号常量和const常量
#define pi 3.14
const double pi = 3.14
都可以,推荐const写法
define可以定义任何语句或片段,但宏定义是直接将对应的部分替换,然后才进行编译,比如
#define cal(x) (x*2 + 1)
如果输入cal(a+1),则直接代入为a+1*2+1,实际上是a+3
运算符
除数被除数都是整型时,答案直接向下取整
自增运算符,i++是先使用i再将i+1,++i是先使i+1再使用i
int a = 1
n1 = a++;
printf("%d %d\n", n1, a);
return 0;
输出1,2
逻辑运算符:&& ab都真才返回真
|| ab都假才返回假
!a 返回相反的结果
条件运算符 A ? B : C
若A真返回B,假返回C
位运算符:无穷大的数设置成(1<<31)-1
更常用的是
const int INF = (1<<30) - 1;
const int INF = 0x3fffffff;
顺序结构
赋值表达式:n+=2 即n=n+2
scanf,printf输入输出
scanf("%d, &n");
常见scanf格式符
数据类型 | 格式符 |
---|---|
int | %d |
longlong | %lld |
float | %f |
double | %lf |
char | %c |
字符串char数组 | %s |
在scanf中只有char可以不加取地址符&
字符数组使用%s读入的时候以空格跟换行为读入结束的标志
如果都是str,输入abcd efg,就会输出abcd
而%c可以读入空格和换行
比如读入1 a bcd,输出a=1,b= ,str=a
常见的printf格式符
和scanf不同在于double类型变量,输出格式变为%f
输出%和\,需要写成%%和\\
三种实用输出格式
%md 不足m位时进行右对齐输出,例如123变为 123,前面两个空格
%0md 同上,只是用0代替空格填充
%.mf 让浮点数保留m位小数输出
getchar和putchar输入输出单个字符
c1 = getchar();
getchar();
第二行没有储存在某个变量中
getchar也可以识别换行符
注释
/* */对之间内容进行注释
//只注释一行
typedef给复杂的数据类型起别名
typedef long long LL;
int main() {
LL a = 123456789012345;
常用math函数
fabs()绝对值
floor()和ceil()向下取整和向上取整
pow(r,p)r的p次方
sqrt()算术平方根
log()自然对数为底取对
sin()cos()tan()
asin()acos()atan()反三角
round() 四舍五入取整
选择结构
if语句
if(条件A){
...
} else{
...
}
省略号中只有一个语句则可以去掉大括号
if(n)等于if(n!=0)
if(!n)等于if(n==0)
if可以嵌套
switch语句
示例
switch(a + b) {
case 2:
...
break;
case 3:
...
break;
default:
...
}
代表a+b为2,3,其他时执行的语句
如果删去break,程序将会从第一个匹配的case开始执行(即将下面所有case都执行一次)
循环结构
while语句
while和if语句很像
while(条件){
...
}
while(n)等于while(n!=0)
while(!n)等于while(n==0)
do while语句
do{
...
}while(条件);
直到while条件不再成立才退出。
do while会先执行循环体一次,再判断循环条件是否为真,不如while实用
for语句
for(表达式A;表达式B;表达式C){
...
}
for循环开始前执行A
B成立则执行省略号,不成立退出循环
退出循环后执行C
C语言中不允许在for语句的表达式A里定义变量(比如int i),但c++可以,所以要保存成.cpp文件才能通过编译
break和continue语句
break在需要的场合下直接退出循环
if(sum >= 2000) break;
continue作用跟break相似,也是切断不执行循环,只是要进入下一个轮回(当下面有轮回时就用continue,否则continue和break都可以用)
int sum = 0;
for(int i = 1; i <= 5; i ++){
if(i % 2 == 1) continue;
sum = sum + 1;//这句话就相当于下一个轮回
}
数组
一维数组定义格式如下:
int a[10];
double bd[2333];
printf("a[%d] = %d\n", i, a[i]);
递推:顺推、逆推,一种顺推为
for(int i = 1; i < 10; i++){
a[i] = a[i - 1] * 2;
}
于是后一个元素为前一个元素乘2
冒泡排序
通过交换把当前剩余元素的最大值移动到一端
第一趟:a[0]与a[1]比,a[1]与a[2]比……大的往右移
第二趟:同上
……
交换:设立中间变量
n个数进行了n-1趟
int a[10] = {3,1,4,5,2};
for(int i = 1; i <= 4; i++){ //进行了n-1趟
//第i趟时从a[0]到a[n - i - 1]都与它们的下一个数进行比较
for(int j = 0; j <5 - i; j++){
if(a[j] > a[j + 1]){ //如果左边的数更大,则交换a[j]和a[j + 1]
int temp = a[j];
a[j]=a[j+1];
a[j+1] = temp;
}
}
}
二维数组
定义
int a[5][6];
double db[10][10];
输入二维数组a的元素
int a[3][3];
for(int i = 0; i < 3; i ++){
for(int j = 0; j < 3; j ++){
scanf("%d",&a[i][j]);
如果数组大小较大(10^6级别,需要定义在主函数外)
#include<stdio.h>
int a[1000000];
int main(){
for(int i = 0; i < 1000000; i++){
...
}
多维数组也类似
memset对数组中每一个元素赋相同的值
要在开头添加string.h头文件,建议初学只赋0和-1,如果赋其他用fill函数
memset(数组名, 值, sizeof(数组名));
int a[5] = {1,2,3,4,5};
//赋初值0
memset(a, 0, sizeof(a));
for(int i = 0; i < 5; i++){
printf("%d ", a[i]);
}
字符数组
可以通过直接赋值字符串来进行初始化(仅限于初始化)
char str[15] = "Good Story!";
输入输出:
scanf,printf对字符类型有%c,%s两种格式
char str[10];
scanf("%s", str);
printf("%s", str);
getchar() putchar()分别用来输入输出单个字符
puts ()和gets()
gets()用来输入一行字符串,gets识别换行符\n作为输入结束,因此scanf完一个整数后,如果要使用gets,先用getchar接收整数后的换行符
字符数组存放方式
末尾有空字符\0表示存放字符串的结尾
如果不使用scanf的%s格式或gets函数输入字符串,一定要在每个字符串后面加入“\0”
string.h头文件
包含许多用于字符数组的函数
strlen()可以得到字符数组中第一个\0前的字符个数
char str[10];
gets(str);
int len = strlen(str);
输入memeda,输出6
strcmp()函数返回两个字符串大小的比较结果,以字典序
strcmp(字符数组1,字符数组2)
如果1<2,返回一个负整数(不同的编译器不一样)
如果1==2,返回0
如果1>2,返回一个正整数
strcpy()把一个字符串复制给另一个字符串
strcpy(字符数组1,字符数组2)
指把字符数组2复制给1,复制包括结束符\0。
strcat()把一个字符串接到另一个后面
sscanf与sprintf
实际上就是string+scanf和string+printf,都在stdio.h头文件下
如
sscanf(str,"%d", &n)
sscanf就是把字符数组str的内容以’’%d’'的格式写到n中
int n = 12;
double db = 3.1415;
char str[100], str2[100] = "good";
sprintf(str, "%d:%.2f,%s", n, db, str2);
printf("str = %s\n", str);
return 0;
输出str = 12:3.14,good