C/C++基础知识回顾
本文最后更新于:2021年5月9日 晚上
# C/C++基础知识
由于在准备考研专业课,感觉最近十分需要补习一下算法,就先回顾一下面向ACM算法题的 C/C++ 的基础知识(主要是C++),顺便记录一下。
00 / C++基础认知
C++是一种通用程序设计语言,支持多重编程模式,例如“过程化程序设计”、“数据抽象”、“面向对象程序设计”、“泛型程序设计”和“设计模式”等。
01 / 从 helloworld.cpp 分析C++基本语法
#include <iostream>
using namespace std;
int main()
{
cout << "hello world!" << endl;
return 0;
}
第1行的代码
#include <iostream>
表示的意思为包含输入输出流的头文件,因为我们需要在屏幕上输出显示一段话,而这需要”借力“编程语言标准库(人话就是,这些标准库像是工具箱,里面装了一些工具,而我们就是使用这些工具,拿首先需要拿到这个工具箱)。语法层次:其中#
是预处理命令的开头,include
代表包含,而iostream
是标准库的名字,<>
是包含系统提供的库。
第2行代码
using namespace std;
代表使用命名空间std,命名空间包含变量名、函数方法名。为了区别某些同名对象和统一化管理,就把他们都定义在一个命名空间当中,方便使用的时候调用,解决不同工程的变量函数等命名冲突的问题。(人话就是,上面有了工具箱的概念了,就像刀这个工具,有手术刀,菜刀,指甲刀等等,它们会按照用途放在不同工具仓库中,仓库中可能有一个工具箱也可能有很多工具箱,而这个用途就是区分它们的关键)。语法层次:using
就是使用,namespace
就是说明是命名空间,std
就是一个叫做标准的命名空间,即C++标准库所在的命名空间,其中需要用到的是cout、cin、endl、string等。
第4行代码
int main()
表示是一个叫做main
函数的定义整体。main
函数也是C-like函数的程序入口,是必不可少的部分(人话就是,要做手术,你得在手术室里使用,函数可以理解为是一个个的工具操作间)。int
代表程序的返回值,是整数类型,main
是函数的名称,()
是参数列表
第5行和第8行的
{}
代表函数体的起止
第6行代码
cout << "hello world!" << endl;
表示在屏幕上输出双引号里面的这句话。cout
和endl
就是在iostream
当中定义的,cout
表示标准输出接口,endl
就是end line,也就是换行。<<
是表示左移操作符(可以简单的理解为是将右边的内容给左边)
第7行的
return 0;
就是匹配第4行的int
返回值的,表示函数运行到这里结束,并且返回需要的内容(人话就是,这台手术完成了,总得告诉结果吧)
using namespace std;
cout << "Hello This fxxking World!" << endl;
return 0;
这些语句结束的时候都带有一个分号,这是因为对于C程序来说,分号代表一个语句的完结(也就是这件事我说完了)。而且,这三句话是不是都带有一种”操作“的含义呢?所以以后设计C代码的时候一定要记得在需要加分号的地方加上分号。
int
return
using
namespace
这些我们称为是保留字或者关键字,也就是C++语言自行需要保留的单词,我们不能随意乱用的。
C的库在C++中只需将后缀.h变成前缀c
例如:
#include <stdlib.h>
//变成
#include <cstdlib>
02 / 基本数据类型
int number = 1;
char character = 'a';
bool bollean = true; //相比C新增布尔类型 true(1) or false(0)
char* cString = "Hello";
string cppString = "World"; // 相比C的字符数组,新增字符串类型,多了更多操作函数。
C++中的结构体类型
struct node
{
int number;
node* next;
};
// C++使用结构体类型时,不需要在前面加一个struct,直接使用结构体的名字。
node* head;
#include <iostream>
using namespace std;
struct st{
int a,b;
// 下面是构造函数,与结构体同名,在创建对应结构体时自动调用。
st(int _a,int _b) // 结构体名(参数列表)
{
// 赋值语句
a = _a;
b = _b;
}
};
int main()
{
st newSt = st(1,2); // 等价于 st = newSt(1,2);
// 注意,若有构造函数则在创建结构体变量时就必须构造,例:st newSt;会报错
printf("%d %d",newSt.a,newSt.b);
return 0;
}
03 / 输入输出
C++的输入输出
- 流输入cin
输入用cin,相当于C里面的scanf。所有标准数据类型都可以用cin输入。
格式:
cin >> 变量名;
例:
cin >> number; // scanf("%d", &number);
cin >> character; // scanf("%c", &character);
cin >> cString; // scanf("%s", cString);
- 流输出cout
将字符串或变量的值压进缓存区然后输出,endl相当于’\n’,同时会清空缓存区。
cout << number << endl;
cout << character << endl;
cout << boolean << endl;
cout << cString << endl;
cout << cppString << endl;
C的输入输出
- C格式化输入scanf
scanf("%[flag]type",&…);
flag | 含义 | flag | 含义 |
---|---|---|---|
* | 跳过 | l | long, double |
数字 | 最大字符数 | ll | long long |
hh | char | L | long double |
h | short |
type | 用于 | type | 用于 |
---|---|---|---|
d | int | s | 字符串(单词) |
i | 整数,可能为十六进制或八进制 则转为十进制int |
[…] | 所允许的字符 |
u | unsigned int | p | 指针 |
o | 八进制 | a,e,f,g | float |
x | 十六进制 | c | char |
- C格式化输出printf
printf("%[flags][width][width][.prec][hIL]type",…);
// flags不填则默认右对齐
Flag | 含义 | width或prec | 含义 | 类型修饰 | 含义 |
---|---|---|---|---|---|
- | 左对齐 | number | 最小字符数 | hh | 单个字节 |
+ | 在前面放+或- | * | 下一个参数是字符数 | h | short |
(space) | 正数留空 | .number | 小数点后的位数 | l | long |
0 | 0填充 | .* | 下一个参数是小数点后的位数 | ll | long long |
L | long double |
type | 用于 | type | 用于 |
---|---|---|---|
i 或d |
int有符号整数型(digit 和 integer) | g 或G |
实数(不显示无意义0)float |
u |
无符号整数型(unsigned int) | a 或A |
十六进制浮点 |
f 或F |
浮点数(float),6 | x |
十六进制 |
e 或E |
科学计数法浮点数,指数(exponent) | X |
字母大写的十六进制 |
c |
char字符型(character) | o |
八进制 |
s |
字符串(string) | p |
指针(pointer)内存地址 |
n |
读入/写出的…个数 | %n 用法 |
ptf("%…%n",…,&num); |
常用输入方式
- 读入一行字符串:getline()
格式:
getline(cin,字符串变量名);
或
cin.getline(字符串变量名,1000); // 1000为读入的字符数上限
相当于C里的gets(cstring);
- 循环读入直至文件结束(判断EOF结束循环)
int n,m;
while(cin >> n >> m)
{
//Do something.
}
-
注意事项
cin方便但速度比scanf慢很多,数据量大(1e5以上)时用scanf;
输出小数需要控制位数时用printf比cout方便,cout要用<iomanip>头文件;
输出double时,在G++中要用%f而非%lf;
使用getline()之前如果有其他输入操作,那么应该在getline()前写一个getchar()来吞掉上一步输入操作留下的换行符’\n’;
04 / 动态内存分配
int* number = new int; // C++中用new来动态开辟内存
int* arr = new int[100]; // C++不支持变长数组,[]里一定是一个常量
int* carr = (int*)malloc(100 * sizeof(int));
写题时动态内存的分配一般用在新建一个结构体上,可以不用手动释放内存。
05 / 引用类型
不像C里需要取址再用指针取值修改,C++直接引用就可以修改值。
例如:
void swap(int &a,int &b){
int tmp = a;
a = b;
b = tmp;
}
int main(int argc, char const *argv[])
{
int x = 1, y = -1;
printf("swap前:x=%i,y=%i\n", x, y);
swap(x, y);
printf("swap后:x=%i,y=%i\n", x, y);
return 0;
}
输出:
swap前:x=1,y=-1
swap后:x=-1,y=1
06 / 函数重载
C++中,两函数名可以相同,但参数值和返回值不同。
至少满足下列一种情况:
- 函数名不同
- 形参类型不同
- 形参个数据不同
- 有缺省值不引起调用时歧义
07 / 运算符重载
重载运算符往往用于重载结构体的运算符,使得结构体也拥有和标准数据类型一样的运算符(一般只需要重载<,重载太多不太好)
格式如下:
bool operator 运算符 (const 结构体名称 b)
{
return(运算符对该结构体成立);
}
例如:
struct student
{
int A_score;
int B_score;
student(int a, int b) : A_score(a), B_score(b){} //构造函数
//在结构体内的运算符重载
bool operator < (const student b){
if(this->A_score!=b.A_score) //优先比较 A_score
return (this->A_score < b.A_score); //如果分数不同,则判断 student1.A_score 小于 student2.A_score时,student1 < student2 为真;
return (this->B_score < b.B_score); // 如果 A_score 相同则比较 B_score;
}
};
using namespace std;
int main(int argc, char const *argv[])
{
student s1(100, 90);
student s2(90, 90);
student s3(90, 99);
cout << "s1<s2?:" << (s1 < s2) << endl;
cout << "s2<s3?:" << (s2 < s3) << endl;
cout << "s1<s3?:" << (s1 < s3) << endl;
return 0;
}
输出:
s1<s2?:0
s2<s3?:1
s1<s3?:0
基础知识先到这里,若有不足之处后续再修改补充,后面回顾STL。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!