首页 > 编程语言 > 详细

[知识点] 1.2 C++入门基础知识

时间:2020-04-22 21:33:05      阅读:61      评论:0      收藏:0      [点我收藏+]

前言

这篇文章对 C++ 里一些最基础的编程知识进行简要介绍。

子目录列表

1、环境与编译

2、头文件

3、注释

4、变量与常量

5、输入与输出

6、格式与缩进

7、#define 与 typedef

8、运算符

9、分支与循环

10、数组与结构体

11、函数

12、文件操作

 

1.2 C++ 入门基础知识

1、环境与编译

① IDE

请参见:https://www.cnblogs.com/jinkun113/p/12741364.html

② 编译器

Windows 下需要自行下载,当然 IDE 可能直接集成了编译器,或者提供了下载渠道。

macOS 在终端执行:xcode-select --install

Linux 在终端执行:sudo apt update && sudo apt install g++

③ 命令行执行

如果不想被 IDE 的框架受限,或者想显得更高端的话,可以在命令行直接进行编译,格式为:

g++ *.cpp -o *,* 表示要编译的文件名,-o 用来指定输出文件名。

除此之外,还有许多可以添加的编译选项,列举几个常用的:

-O / -O1 优化生成代码;-O2 进一步优化;-O3 再进一步优化;

-w 关闭所有警告提醒;-Wall 显示所有警告提醒;

-lm 链接数学库(这个一般竞赛编译都会加上,但其实不加上也能正常运行)

 

2、头文件与主函数

先演示一个最经典的示例代码。

1 #include <iostream>
2 using namespace std;
3 
4 int main() {
5     cout << "Hello, world!"; // output ‘Hello, world!‘
6     return 0;
7 } 

① 头文件

其中,第一行(L1)为头文件格式:

#include <头文件名>

头文件的作用是什么?一般,头文件包含了各类功能函数或者数据接口声明。任何函数都不是与生俱来的,而是保存在 C++ 里内置的各种 .h 文件中,如果不事先声明,编译器并不能识别这是什么。

比如,L5 的 cout 函数(4、输入和输出会介绍)是来自内置的 <iostream> 中,故需要在最开始表明,接下来的代码需要用到这里面的函数,那么编译器在执行主程序之前就会先进行预处理。

一般而言,只需要写上你需要的头文件即可,都有时候可能出现遗漏,而编译器并不会在所有这类情况下报错,所以你可以选择:

① 提前写好常用的头文件作为模板,每次编写时直接复制上去;

② 多检查几次(

③ 使用万能头文件:

#include <bits/stdc++.h>

它包含了 C++ 绝大多数头文件。但是请注意,首先 C 语言不能使用,MSVC 编译器不支持;其次并不是所有情况下都允许使用,多加留意规则;然后,头文件声明越多,对编译时间影响越大,尽管一般不至于导致 TLE。

头文件也可以自己编写,比如自行定义了 “hzq.h”,并在其中定义了一些函数,那么在声明头文件时可以这样写:

#include "hzq.h"

注意,使用 " " 而不是 < >。

一般使用不到,尤其竞赛就不可能用到了,所以暂时不过多介绍。

② 命名空间 namespace

L2 表示使用标准命名空间。请参见:https://www.cnblogs.com/jinkun113/p/12744678.html

③ 主函数 main

L3 定义了一个主函数:int main()。任何 .cpp 有且仅有一个主函数,且为整型(int)函数。注意,请不要使用各类古老的教材教辅上写的 void main(),实际上这种写法早已被废弃。

L6 有一句 “return 0”,表示主函数的返回值为 0,作为主函数的结束标识,尽管可以不写,但还是建议写上,这是规范。

更多关于函数的概念,请参见:<施工中>

 

3、注释

还是上面的示例代码。注意到 L5 后面有个 “//” 符号,其表示注释,对程序编译无任何影响,一般用于让某段代码暂时不执行,或者解释程序,便于日后维护或者供他人阅读。

两种注释的方法:

① 行内注释,以 “//” 开头,后面所有内容全部为注释;

② 注释块,以 “/*” 开头,以 “*/” 结尾,可以跨行,中间内容全部为注释。

 

4、变量与常量

① 变量

变量,指没有固定值而可以改变的数,一般用非数字符号表达,在计算机语言中是相对关键的一类数。

C++ 中定义了如下基本数据类型:

int - 整型,表示整数,占用 4 个字节,表示范围为 [-2147483648, 2147483647 (= 2 ^ 31 - 1)],还有:

short int - 短整型,占用 2 个字节,表示范围为 [-32768, 32767 (= 2 ^ 15 - 1)];

long long int - 长整型,占用 8 个字节,表示范围为 [-9223372036854775808, -9223382036854775807 (= 2 ^ 63 - 1)],可缩写为 long long;

float - 单精度浮点型,表示小数,占用 4 个字节,表示范围大致为 [-3.4 * 10 ^ 38, 3.4 * 10 ^ 38];

double - 双精度浮点型,表示小数,占用 8 个字节,表示范围大致为 [-1.7 * 10 ^ 308, 1.7 * 10 ^ 308];

char - 字符型,表示字符,占用 1 个字节,表示范围为 [0, 255];

bool - 布尔型,表示真或假,占用 1 个字节,表示范围为 [0, 1];

void - 无类型

还有一些不太常用的暂时不列。

声明变量的格式:

变量类型 变量名, ...

比如:

int a;

double b;

char c = ‘a‘;

声明的同时可以赋值。

② 常量

常量与变量相对,表示不会改变的数,声明时直接附加一个 const,且必须赋值,比如:

const int a = 2;

③ 作用域

写在主程序外的变量称为全局变量,其作用域为整个程序;其他的为局部变量,其作用域是声明语句所在的代码块,只能在所属代码块或者所属函数中使用。至于代码块怎么理解,可以视作一对 {} 为一个代码块。

虽然称之为全局/局部变量,其实对于常量而言也是一样的。不过对于变量,还有一点需要注意:全局变量声明时没有赋值则初始化为 0;局部变量不会初始化,是出现 bug 很常见的起因。

 

5、输入与输出

① cin / cout

继续看上面的示例代码。注意到 L5 使用了一个函数 cout,其作用为输出到屏幕,其格式为:

cout << ...;

... 后可以继续接 << ...,理论上无限制,表示继续输出。下面是一些例子:

cout << "hi"; // 表示输出 “hi”

cout << 1 << ‘ ‘ << 2; // 表示输出一个 1 和一个 2,中间有一个空格

cout << a << endl; // 表示输出一个变量 a,并换行

cin 作用是从键盘输入,使用方法类似于 cout,只是符号相反:

cin >> a >> b; // 表示输入两个变量 a, b

它们特属于 C++,被称作输入输出流函数

② scanf / printf

它们其实是属于 C 语言的,相比 cin / cout,速度更快,只是格式较为复杂。以 scanf 举例,格式为:

scanf("...", ...);

"..." 内填写字符或者格式说明符,... 填写变量。

scanf("%d", &a); // 表示输入一个变量 a

scanf("%d %d", &a, &b); // 表示输入两个变量 a, b

printf("1"); // 表示输出一个数 1,等同于 printf("%d", 1);

printf("%d\n%d", a, b); // 表示输出两个变量 a, b,中间会换行

一一解释:

> %d 是什么?

格式说明符的一种。使用 scanf / printf 时,需要先声明该变量的格式,下面是常用的格式说明符:

%d - 有符号整型变量;%c - 字符变量;%s - 字符串(字符数组)变量;

%lf - 双精度浮点型变量;%lld - 长整型变量(Windows 下使用 %I64d)。

其中,%d 和 %lf 还可以添加其他条件:

%*d - * 表示控制整型变量显示长度,比如 * 小于数本身位数没有影响;大于本身位数将自行填充空格。

举例:printf("%3d", 5); // 将输出 “  5”

%*lf - * 表示小数保留位数。

举例:printf("%.2lf", 2.077); // 将输出 “2.08”

> \n 是什么?

转义字符的一种。使用 scanf / printf 时,用于表示一些不能直接输入的字符,下面是常用的转义字符:

\n - 换行符;\t - 制表符;\" - 表示 ";\\ - 表示 \。

> scanf 中的 & 是什么?

& 表示取址运算符,表示变量在内存中的地址。具体请参见:<施工中>

 

6、格式与缩进

C++ 对书写格式和缩进并无任何规定,理论上只要语法正确,想怎么写怎么写。但语言是什么?是人类进行沟通表达和传递信息的工具,不要满足于计算机能理解你的行为,所以尽可能地保持代码的格式统一和结构清晰,能形成自己的代码风格更好。当年在 cj 搞 OI 那么久,早期风格变化大,后来慢慢定型了,基本上是师承 bebe 的,过了若干年再次看到他的代码的时候发现还是那么像。。

对于格式,可能大多是在空格出现频率和换行频率上有一定差异;

对于缩进,一般有四格缩进和两格缩进的区别。

见仁见智。

粘贴一份 KMP 算法的代码体现一下代码风格。。

 1 int main() {
 2     cin >> a + 1 >> b + 1;
 3     la = strlen(a + 1), lb = strlen(b + 1);
 4     fail[0] = -1;
 5     for (int i = 1, x = -1; i <= lb; i++) {
 6         while (x >= 0 && b[x + 1] != b[i]) x = fail[x]; 
 7         fail[i] = ++x;
 8     }
 9     for (int i = 1, x = 0; i <= la; i++) {
10         while (x >= 0 && b[x + 1] != a[i]) x = fail[x];
11         if (++x == lb) cout << i - lb + 1, exit(0);
12     }
13     cout << "N/A";
14     return 0; 
15 }

以前我更不喜欢换行,现在可能好点了(

 

7、#define 与 typedef

① #define

和 #include 一样,#define 也是一种预处理命令,用于定义宏,本质上是一种文本替换,格式为:

#define A B

可以使程序中所有 A 全部视作 B,使用起来比较灵活,比如:

#define N 2020

printf("%d", N); // 将输出 2020

还可以带参数,比如:

#define printf("%d", &N) PRINT(N)

PRINT(5); // 将输出 5

也正是因为使用很灵活,有时容易出现一些不可预见的问题,比如:

#define sum(A, B) A + B

int c = 2 * sum(3, 4);

看起来是先求 3 + 4 = 7 再 7 * 2 = 14,但实际上会被理解为:

int c = 2 * 3 + 4;

故最后结果为 10 而非 14。

所以建议一般只在进行简单的替换时才使用 #define,比如:

int a[20000], b[20000], c[20000], d[20000];

输出这么多次 20000 又麻烦又不美观,这时可以:

#define MAXN 20000

② typedef

专用于给类型定义新的名字。格式为:

typedef 原类型名 新类型名;

可以用于原类型名太长而需要简化的情况,比如:

typedef long long ll;

相比 #define,功能较弱,但是更为规范,会进行正确性检查。

还有许多用途,这里暂时不再叙述。

 

8、运算符

① 算术运算符

+ 正/加法;- 负/减法;* 乘法;/ 除法;% 取模。

② 位运算符

~ 非;& 与;| 或;^ 异或;<< 左移;>> 右移。

具体使用和意义请参见:<施工中>

③ 赋值运算符

= 赋值,前面还可以加上算术运算符,比如:

i += 2,等价于 i = i + 2;

i %= j,等价于 i = i & j。

④ 自加自减符

++ 自加:i++ 等价于 i = i + 1;

-- 自减:i-- 等价于 i = i - 1;

更多使用方法和意义请参见:<施工中>

⑤ 比较运算符

< 小于;<= 小于等于;> 大于;>= 大于等于;== 等于;!= 不等于。

注意,== 表示等于,而 = 表示赋值,初学者常见问题之一。

⑥ 逻辑运算符

&& 逻辑与;|| 逻辑或;! 逻辑非。

注意和前面的位运算符区分开来:位运算符是返回与/或/...操作的值,而逻辑运算符只返回其值是否为 0,为 0 时返回 0,其余情况就返回 1,用于各类判断而非运算。

⑦ 分号与逗号

; 分号:表示一个表达式的结束;

, 逗号:用于将若干个表达式分隔开,有时候等价于分号,但实际有区别,这里不赘述。

⑧ 成员访问运算符

[ ] 数组下标(10、数组与结构体会介绍);

对象成员(对象请参见:https://www.cnblogs.com/jinkun113/p/12744678.html);

& 取地址/获取引用符;* 寻址/解引用符;-> 指针成员;

(关于这些具体请参见:<施工中>)

> 关于优先级

所有运算符都有运算的先后顺序,就像我们平常计算的时候知道乘除优先于加减,下面给出C++ 大部分运算符的优先级总表:

技术分享图片

 

9、分支与循环

① 分支

> if 和 if - else 语句

<暂略>

> switch 语句

switch (选择句) {
    case 标签1:
        主体1; break;
    case 标签2:
        主体2; break;
    ... 
    default:
        主体n; 
}

其含义为:当选择句的返回值为标签 1 时,执行主体 1 语句;为标签 2 时,执行主体 2 语句,等等;如果不等于任何标签,则执行 default 中的主体 n 语句。

标签本身没有数量限制,但最后必须写 default。

其中,选择句必须是整数类型表达式,标签必须是整型常量,所以相比之下局限性比 if - else 大很多。

注意每一个 case 后都写上了 break,从 switch 的功能来看是必要的,但是如果不加,编译是没有问题的,只是会出现不一一对应执行的情况,比如:

在第二个 case 中不加 break,且选择句返回值为标签 2,则将会执行主体 2, 3, ... 的语句,直到出现 break。

② 循环 <暂略>

> for 语句

> while 语句

> do - while 语句

> break 和 continue

 

10、数组与结构体

<暂略>

 

11、函数

<暂略>

 

12、文件操作

不涉及文件操作的时候,程序的输入输出都是直接在终端中进行的,引入文件操作后,可以使我们的程序从指定文件中读入数据,再将数据输出到指定文件。

① freopen 函数

一般格式:

freopen(文件名, "模式", 流);

部分模式列表:

r - 只读;w - 只写;r+ - 读写,文件必须存在;w+ - 读写,会自动新建;

a - 只写,不存在会自动新建,存在会直接将数据附加在文件末尾,保留 EOF 符;

a+ - 同 a,但不保留 EOF 符。

比如:

freopen("data.in", "r", stdin);

freopen("data.out", "w", stdout);

关闭文件(可以不写):

fclose(stdin);

fclose(stdout);

② fopen 函数

格式和 freopen 类似:

fopen(文件名, "模式");

区别在需要定义文件指针,比如:

FILE *in, *out;

in = fopen("data.in", "r");

out = fopen("data.out", "w");

与此同时,输入输出的函数需要进行修改,比如:

fscanf(in, "%d", &a);

fprintf(out, "%d", a);

相对比较麻烦,平时用的不太多。

③ fstream 函数

C++ 特有,名为“文件输入输出流”,格式为:

fstream 流名(文件名);

比如:

fstream file("data.txt");

其中,fstream 可以更改为 ifstream 或 ofstream,表示只支持读 / 写。

中间的读写函数从 cin / cout 改成 file 即可。

关闭文件:

流名.close();

[知识点] 1.2 C++入门基础知识

原文:https://www.cnblogs.com/jinkun113/p/12755769.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!