基本程序结构分为头文件和主函数,C语言文件扩展名为.c,C++文件扩展名为.cpp。
#include
int main(){
int a,b;
scanf("%d%d",&a,&b);
printf("%d",a+b);
return 0;
}
stdio.h是标准输入输出库,用于程序输入输出,其全称为standard input output,h是head的缩写,.h是头文件的格式,使用#include<…>的写法来包含头文件使用其相关函数,且在C++中,推荐使用等价写法:cstdio。
一个程序至多有一个主函数,它是程序的执行入口。
变量是在程序运行过程中其值可以改变的量,先定义后使用,定义时可以赋初值:
变量类型 变量名 = 初值;
基本数据类型分为整型、浮点型、字符型,C++中又包括布尔型。
整型分为短整型(short)、整型(int/long int)、和长整型(long long/long long int)。整型位数是32bit,取值范围是-231~+(231-1);长整型位数是64bit,取值范围是-263~+(263-1),长整型赋初值后加LL。
浮点型分为单精度(float)和双精度(double)。单精度位数为32bit,其中1bit符号位,8bit指数位,23bit尾数位,存放的浮点数范围是-2128~+2128,有效精度6~7位;双精度位数为64bit,其中1bit符号位,11bit指数位,52bit尾数位,存放的浮点数范围是-21024~+21024,有效精度15~16位。因此浮点型数据尽量用double来存储。
字符变量的定义:
char c = 'e';
该语句定义了一个字符变量c并把字符常量e赋值给它,字符常量必须是单个字符且要用单引号标注以区分于字符变量。
C语言中,字符常量使用ASCII码统一编码,标准ASCII的范围是0~127,A~Z的ASCII码是65~90,a~z的ASCII码是97~122。
ASCII码中一些无法显示的控制字符可以通过右斜线加特定的字母来表示,这种情况下斜线后的字母失去了本身的含义,因此称为转义字符。
字符串常量是由双引号标记的字符集,C语言中没有单独一种基本数据类型可以存储,只能使用字符数组的方式,C++中有string类型。
布尔(bool)型在C++中可直接使用,但在C语言中须添加stdbool.h头文件,布尔型变量取值只能是ture(真)或false(假),分别代表非零与零。
强制类型转换格式:
(新类型名)变量名
符号常量即用标识符来代替常量,又称为“宏定义”,其格式如下:
#define 标识符 常量
但推荐使用const:
const 数据类型 变量名 = 常量;
+、-、*、/(整型相除结果向下取整)、%、++、–。
<、>、<=、>=、==、!=。
&&、||、!。
C语言中唯一的三目运算符是条件运算符:
A ? B : C;
若A为真,执行返回B的结果;若A为假,执行返回C的结果。
<<、>>、&、|、^、~。
C语言中用等号“=”实现赋值操作,多个变量赋予同一值可以使用连续等号,将其他运算符放在赋值运算符前构成复合赋值运算符可以加快编译速度,提高代码可读性。
输入函数scanf格式如下:
scanf("格式控制",变量地址);
常见数据类型变量的scanf格式符:
数据类型 | 格式符 | 举例 |
---|---|---|
int | %d | scanf("%d",&n); |
long long | %lld | scanf("%lld",&n); |
float | %f | scanf("%f",&fl); |
double | %lf | scanf("%lf",&db); |
char | %c | scanf("%c",&c); |
字符串(char数组) | %s | scanf("%s",str); |
输出函数printf格式如下:
printf("格式控制",变量名称);
常见数据类型的printf格式符:
数据类型 | 格式符 | 举例 |
---|---|---|
int | %d | printf("%d",n); |
long long | %lld | printf("%lld",n); |
float | %f | printf("%f",fl); |
double | %f | printf("%f",db); |
char | %c | printf("%c",c); |
字符串(char数组) | %s | printf("%s",str); |
三种常用输出格式:
(1)%md
使不足m位的int型变量以m位进行右对齐输出,高位用空格补齐。
(2)%0md
和%md作用相似,但高位使用0补齐。
(3)%.mf
使浮点数保留m位小数输出。
getchar用来输入单个字符,putchar用来输出单个字符。
对语句进行注解,程序编译时自动跳过注释。
(1)使用“/**/”注释
/**/对“/*“和”*/“之间的内容进行注释。
(2)使用”//“注释
//可以注释一行中在该符号之后的所有内容。
可以给复杂数据类型起别名:
typedef 数据类型 别名;
使用C语言math函数需要在程序开头加上math.h头文件。
对double型变量取绝对值。
分别对double型变量向下取整和向上取整。
返回rp。
返回double型变量的算数平方根。
返回double型变量的以自然对数为底的对数。
分别返回double型变量的正弦值、余弦值和正切值,参数要求是弧度制。
分别返回double型变量的反正弦值、反余弦值和反正切值。
将double型变量四舍五入,返回类型也是double型。
if语句格式:
if(条件A){
...
}else if(条件B){
...
}else{
...
}
先判断条件A是否成立,若A不成立,则判断条件B是否成立,若B仍不成立,才执行最后一个省略号的内容。
if条件的简写:
(1)如果表达式是”!=0“,则可以省略”!=0“。
(2)如果表达式是”==0“,则可以省略”==0“,并在表达式前添加非运算符”!“。
在if或else的执行内容中使用if语句。
用于多分支条件,精简代码,格式如下:
switch(表达式){
case 常量表达式1;
...
break;
case 常量表达式2;
...
break;
case 常量表达式n;
...
break;
default:
...
}
格式如下:
while(条件A){
...
}
先执行后判断,格式如下:
do{
...
}while(条件A);
格式如下:
for(表达式A;表达式B;表达式C){
...
}
先执行表达式A,判断表达式B,不成立退出循环,成立则执行省略号内容,然后执行表达式C,最后再判断表达式B,循环往复。
break可以强制退出switch语句和循环。
continue可以临时结束循环的当前一轮。
数组就是把相同数据类型的变量组合在一起而产生的数据集合。
一维数组的定义格式如下:
数据类型 数组名[数组大小];
数组大小必须是整数常量。
数组元素的访问格式:
数组名称[下标]
下标从0开始。
一维数组初始化时,需要给出用逗号隔开的从第一个元素开始的若干个元素的初值,并用大括号括住。若想给整个数组都赋初值0,只需把第一个元素赋为0,或只用一个大括号来表示。
排序是指将一个无序序列按某个规则进行有序排序。
冒泡排序从一侧开始,依次比较相邻两个元素,若为逆序则交换,到另一侧结束此为一趟“冒泡”,至多进行n-1趟排序完成。
二维数组是数组元素为一维数组的数组,同理,n维数组是数组元素为n-1维数组的数组。
二维数组定义格式:
数据类型 数组名[第一维大小][第二维大小];
二维数组初始化时,需要按第一维的顺序依次用大括号给出第二维的初始化情况,然后将它们用逗号隔开,并用大括号全部括住。
如果数组过大(106级别),需要将其定义在主函数外。
使用menset函数需要在程序开头添加string.h头文件。
menset函数格式为:
menset(数组名,值,sizeof(数组名));
除和普通数组一样的初始化方式,字符数组还可以通过直接赋值字符串来初始化。
scanf使用格式符%s来输入字符串并保存在字符数组里,通过空格或换行来识别一个字符串的结束。
用于单个字符的输入输出。
gets用来输入一行字符串(识别换行符\n作为输入结束),并将其存放于一维数组中;puts用来输出一行字符串,即输出一维数组,并紧跟一个换行。
字符数组的末尾有一个空字符\0表示存放的字符串的结尾,其ASCII码为0,即空字符NULL,占用一个字符位。空字符\0在使用gets或scanf输入字符串时会自动添加,作为puts和printf字符串输出结束标志。
得到字符数组中第一个\0前的字符的个数,格式如下:
strlen(字符数组)
返回两个字符串大小按字典序的比较结果,格式如下:
strcmp(字符数组1,字符数组2)
把字符数组2复制给字符数组1,格式如下:
strcpy(字符数组1,字符数组2)
把字符数组2接到字符数组1后面,格式如下:
strcat(字符数组1,字符数组2)
sscanf可以把字符数组内容写入变量,格式为:
sscanf(字符数组,"格式控制",变量地址);
sprintf可以把变量内容写入字符数组,格式为:
sprintf(字符数组,"格式控制",变量名称);
函数是一个实现一定功能的语句的集合。
函数的语法格式如下:
返回类型 函数名称(参数类型 参数){
函数主体
}
与函数相关的两种变量:
(1)全局变量
在定义之后的所有程序段内都有效的变量(即定义在所有函数之前)。
(2)局部变量
定义在函数内部,且只在函数内部生效,函数结束时销毁。
返回类型为int型的main函数返回0即程序正常终止。
函数的参数可以是数组,且数组作为参数时,数组的第一维不需要填写长度(第二维需要填写),实际调用时也只需填写数组名。
数组作为参数时,在函数中对数组元素的修改就等同于对原数组元素的修改。
在一个函数中调用另一个函数。
一个函数调用该函数自身。
C语言中用“指针”来表示内存地址,而如果这个内存地址恰好是某个变量的地址,那么又称“这个指针指向该变量”。
在变量前加上取地址运算符&,就表示变量的地址。
指针其实是一个unsigned类型的整数。
指针变量用来存放指针(内存地址),定义时在数据类型后加*来表示这是一个指针变量:
数据类型* 变量名称;
在指针变量前加*即可获得指针变量存放的地址所指的元素。
指针变量(或者说内存地址)可以进行以数据类型为单位的加减法。
数组是由地址上连续的若干个相同类型的数据组合而成,数组名称可作为数组的首地址使用,而赋值给指针变量。
指针类型可以作为函数参数的类型,这时视为把变量的地址传入函数,如果在函数中对这个地址中的元素进行修改,则原来的数据确实会被改变。
C++中的引用不产生副本,而是给原变量起了别名,对引用变量的操作就是对原变量的操作。
引用的使用方法是在函数的参数类型后或参数名称前加上&。
指针作为参数类型时,使用引用,在函数内对指针变量的修改就会作用到原指针变量上。
引用是产生变量的别名,常量不可使用引用。
结构体可以将若干个不同数据类型的变量或数组封装在一起,以储存自定义的数据结构,方便储存一些复合数据。
格式如下:
struct Name {
//一些基本的数据结构或者自定义的数据类型
};
访问结构体内的元素有两种方法:“.”操作和“->”操作。
构造函数是用来初始化结构体的一种函数,它定义在结构体内,不需要写返回类型,且函数名与结构体名相同。
结构体内部会生成默认的构造函数,当重新定义构造函数时,默认生成的构造函数会被覆盖。构造函数支持重载。
C++中的输入输出函数,使用时需要添加头文件“#include
cin是c和in的合成词,采用输入运算符“>>”进行输入。
cout是c和out的合成词,采用输出运算符“<<”进行输出。
cout可以使用\n或endl(end line)来表示换行。
计算机采用有限位的二进制编码,浮点数在经过大量计算后可能会产生误差,因此引入一个极小数eps对误差进行修正。
如果一个数a落在了[b-eps,b+eps]的区间中时,就应当判断为a == b成立。经验表明,eps取10-8比较合适,因此可以将eps定义为常量1e-8:
const double eps = 1e-8;
为了使比较更加方便,把比较操作写成宏定义形式:
#define Equ(a,b) ((fabs((a)-(b)))<(eps))
宏定义如下:
#define More(a,b) (((a)-(b))>(eps))
宏定义如下:
#define Less(a,b) (((a)-(b))<(-eps))
宏定义如下:
#define MoreEqu(a,b) (((a)-(b))>(-eps))
宏定义如下:
#define LessEqu(a,b) (((a)-(b))<(eps))
由cos(pi) = -1可知pi = arccos(-1),因此只需把pi写成常量acos(-1.0)即可:
const double Pi = acos(-1.0);
时间复杂度是算法需要执行基本运算的次数所处的等级,其中基本运算就是类似加减乘除这种计算机可以直接实现的运算。时间复杂度是评判算法时间效率的有效标准。
和时间复杂度相似,空间复杂度表示算法需要消耗的最大数据空间。
编码复杂度是一个定性的概念,没有量化标准,用来描述算法思想及代码量是否冗长。
黑盒测试是指:系统后台会准备若干组输入数据,然后让提交的程序运行这些数据,若输出结果与正确答案完全相同,则称通过了黑盒测试,否则根据错误类型返回不同的结果。
根据黑盒测试是否对每组测试数据都单独测试或是一次性测试所有测试数据,又可分为单点测试和多点测试。
系统会判断每组数据的输出结果是否正确,如果输出正确,那么对该组数据来说就通过了测试,并获得这组数据的分值,题目的总得分等于通过的数据的分值之和。
多点测试要求程序能一次运行所有数据,并要求所有输出结果完全正确才能算作通过,只要其中有一组数据的输出错误,本题得0分。由于要求程序能运行所有数据,因此必须保证程序有办法反复执行代码的核心部分,也就要用到循环。而题目一般有3种输入的格式,需要采用相应的输入方式。
(1)while…EOF型
如果题目没有给定输入的结束条件,那么就默认读取到文件末尾,scanf函数的返回值为其成功读入的参数的个数,当读取文件时到达文件末尾导致无法读取现象,产生读入失败,scanf函数返回-1,C语言中使用EOF(End Of File)来代表-1,所以可以利用scanf的返回值是否为EOF来判断输入是否结束。代码如下:
while(scanf("%d",&n) != EOF){
...
}
(2)while…break型
题目要求当输入的数据满足某个条件时停止输入。有两种写法:一是在while…EOF的内部进行判断,满足退出条件时中断(break)当前while循环;二是把退出条件的判断放到while语句中,用逗号与scanf隔开。
(3)while(T–)型
题目给出测试数据的组数,然后给出相应数量组数的输入数据。用一个变量T存储测试数据组数,并在程序开始时读入,之后进行T次循环,每次循环解决一组数据的输入与输出。
常见的输出类型也有3种。
(1)正常输出
输出数据是连续的多行。
(2)每组数据输出之后都额外加一个空行
每组输出结束后额外输出一个换行符\n即可。
(3)两组输出数据之间有一个空行,最后一组数据后面没有空行
这一般是在第三种输入类型while(T–)的情况下,通过判断T是否已经减小到0来判断是否应当输出额外的换行。