c++ 支持两种注释方式:
//line comment
/* block comment can occupy
multiple lines */
在 cpp 文件的开头通常会有 #include
这样的指令,叫做预处理器 (preprocessor), 作用是引入 iostream
库中的函数,其他还有 #inlcude
, #include
, etc.
在程序中常可以见到 using namespace std;
, 作用是让 std 库中的所有元素对当前文件可见。例如在程序中使用打印功能,在使用了上述语句后,可以直接 cout<<"hello world!";
, 否则,需要指定访问,例如,std::cout<<"hello world!";
, 符号 ::
是域访问符。
看一下最简单的程序结构:
//my first program in c++
#include
using namespace std;
int main() {
cout<<"hello world";
return 0;
}
main 函数是 c++ 程序运行的入口执行函数,不论它在程序的哪个位置,程序启动时,它都会执行。
在 c++ 中,标示符由 字母、数字、下划线 组成,且首字母不能是数字,更重要的是,标示符是大小写敏感的。值得注意的是,定义的标示符名称不能和标准 c++ 预留的关键字重名,以下是标准 c++ 预留的关键字(特殊的 c++ 编译器可能还包括自身的预留关键字)。
alignas, alignof, and, and_eq, asm, auto, bitand, bitor,
bool, break, case, catch, char, char16_t, char32_t, class,
compl, const, constexpr, const_cast, continue, decltype,
default, delete, do, double, dynamic_cast, else, enum,
explicit, export, extern, false, float, for, friend, goto,
if, inline, int, long, mutable, namespace, new, noexcept,
not, not_eq, nullptr, operator, or, or_eq, private,
protected, public, register, reinterpret_cast, return,
short, signed, sizeof, static, static_assert, static_cast,
struct, switch, template, this, thread_local, throw, true,
try, typedef, typeid, typename, union, unsigned, using,
virtual, void, volatile, wchar_t, while, xor, xor_eq
以下是 c++ 中所有的基本类型:
分组 | 类型名 | 大小/精度 |
---|---|---|
字符型 | char | 一个字节, 至少 8 位 |
char16_t | 大于 char, 至少 16位 | |
char32_t | 大于 char16_t, 至少 32位 | |
wchar_t | 可以表示最大的字符集 | |
带符号整型 | signed char | 和 char 一样, 至少 8位 |
signed short int | 大于 char, 至少 16位 | |
signed int | 大于 short, 至少 16位 | |
signed long int | 大于 int, 至少 32位 | |
signed long long int | 大于 long, 至少 64位 | |
无符号整型 | unsigned char | 和其对应的带符号整型大小一样 |
unsigned short int | 同上 | |
unsigned int | 同上 | |
unsigned long int | 同上 | |
unsigned long long int | 同上 | |
浮点型 | float | |
double | 精度大于 float | |
long double | 精度大于 double | |
布尔型 | bool | |
void 型 | void | 无存储 |
空指针 | decltype(nullptr) |
上述表格中倾斜字体部分可以省略不写。
基本类型中除了
char
类型具有一个字节的准确大小外(一个字节),其他类型都没有确定的大小,这是因为在众多编译器和机器上无法确定标准的大小。每个具体的编译器都会指定确定的类型大小,这样的设计可以让 c++ 更灵活地适应所有的平台,不管现在还是将来。类型的大小是按位来表示,类型的位数越大,可以表示的值越多,同时占用的空间也越大。
大小 | 可表示的值的个数 | 备注 |
---|---|---|
8 位 | 256 | =28 |
16 位 | 65 536 | =216 |
32 位 | 4 294 967 296 | =232 (~4 billion) |
64 位 | 18 446 744 073 709 551 616 | =264 (~18 billion billion) |
int a;
int b;
int c;
或
int a, b, c;
c++ 支持三种方式的变量初始化形式:
//c-like initialization
int x = 0;
//constructor initialization
int x(0);
//uniform initialization
int x{0};
当一个新的变量初始化时,编译器可以通过初始化推断出变量的类型。
int foo = 0;
auto bar = foo; //the same as: int bar = foo;
当变量未初始化时,可以通过 decltype 推断。
int foo = 0;
decltype(foo) bar; //the same as: int bar;
string 类型是 c++ 中的一种复合类型,string 类型的变量能够存储字符序列。和基本类型不同的是,使用 string 类型需要引入头文件
。
#include
#include
using namespace std;
int main(){
string mystring;
mystring = "hello world";
cout<
string 类型的变量同样支持三种初始化方式:
string mystring = "hello";
string mystring("hello");
string mystring{"hello"};
字面常量可以分为:整型、浮点型、字符型、字符串型、布尔型、指针型 和用户自定义型。
整型常量:
十进制、八进制、十六进制对 75 的表示:
75 //decimal
0113 //octal
0x4b //hexadecimal
默认地,整形的常量的类型是 int
, 但是,可以通过加上特定的尾缀来指定不同的整型类型,尾缀不区分大小写。
尾缀 | 类型 |
---|---|
u or U | unsigned |
l or L | long |
ll or LL | long long |
示例:
75 //int
75u //unsigned int
75l //long
75ul //unsigned long
75lu //unsigned long
浮点型常量:
示例:
3.14159 // 3.14159
6.02e23 // 6.02 x 10^23
1.6e-19 // 1.6 x 10^-19
3.0 // 3.0
浮点型常量的默认类型是 double
, 同样可以通过添加尾缀来指定特定浮点类型。
尾缀 | 类型 |
---|---|
f or F | float |
l or L | long double |
示例:
3.14159L // long double
6.02e23f // float
字符和字符串型常量:
示例:
'm';
"hello";
用转义码来表示特殊字符:
转义码 | 描述 |
---|---|
\n | 换行 |
\r | 回车 |
\t | 水平制表 |
\v | 垂直制表 |
\b | 退格 |
\f | 换页 |
\a | 响铃 |
\’ | 单引号字符 |
\” | 双引号字符 |
\? | 问好 |
\\ |
反斜杠 |
示例:
"Left \t Right"
"one \n two \n three"
多个字符串常量可以通过空格甚至换行符连接起来。
"this forms" " a single" " string "
"of characters"
//以上等于
"this forms a single string of characters"
一个长的字符串常量可以用反斜杠分成多行。
x = "string expressed in \
two lines"
//以上等于
x = "string expressed in two lines"
使用不同的前缀指定不同的字符类型:
前缀 | 类型 |
---|---|
u | char16_t |
U | char32_t |
L | wchar_t |
注意,这里的前缀是区分大小写的。
同样可以使用不同的前缀指定不同的字符串类型:
前缀 | 类型 |
---|---|
u8 | 程序执行期间用 utf-8 进行编码的字符串常量 |
R | 表示原始字符串的字符串常量 |
在原始字符串中,常量内容是由一个起始 R"sequence(
和一个截止)sequence"
来分隔的,这里的 sequence
可以是任意字符序列(包括空序列),字符串的内容位于括号之间,忽略分隔字符序列本身。
例如:
R"(string with \backslash)"
R"&%$(string with \backslash)&%$"
以上两个字符串都等于 "string with \\backslash"
, 前缀 R 也可和 u, L 或 u8 绑定。
其他类型常量:
示例:
bool foo = true;
bool bar = false;
int* p = nullptr;
#include
using namespace std;
//给常量值命名
const double pi = 3.14159;
const char newline = '\n';
int main(){
double r = 5.0;
double circle;
circle = 2 * pi * r;
cout<
作为另一种给常量命名的机制,形式如下:#define identifier replacement
代码中任何出现 identifier
的地方都会被 replacement
替换,replacement
可以是任意字符序列(直到行末),这种替换由预处理器在程序编译之前执行,因此这样的替换不会进行类型或语法检查。
示例:
#include
using namespace std;
#define PI 3.14159
#define NEWLINE '\n'
int main(){
double r = 5.0;
double circle;
circle = 2 * PI * r;
cout<
示例一:
y = 2 + (x = 5);
//以上等于
x = 5;
y = 2 + x;
示例二:
x = y = z = 5;
示例:
x = 11 % 3; //2
示例:
y += x; // 等于 y = y + x;
x -= 5; // 等于 x = x - 5;
x /= y; // 等于 x = x / y;
price *= units + 1; // 等于 price = price * (units + 1);
示例:
x = 3;
y = ++x; // x = 4, y = 4
x = 3;
y = x++; // x = 4, y = 3
示例:
a = 2; b = 3; c = 6;
a == 5; //false
a * b >= c; //true
b + 4 > a * c; //false
(b = 2) == a; //true
短路操作:
示例:
result = codition ? result1 : result2;
//1. condition 为 true, result 为 result1.
//2. condition 为 false, result 为 result2.
示例:
a = (b = 3, b + 2);
//结果: a = 5, b = 3.
示例:
4 << 1; //8
4 >> 1; //2
示例:
int i;
float f = 3.14;
i = (int) f; //c-like style
i = int (f); //function sytle
sizeof 函数接受一个参数,可以是基本类型或者变量,返回字节数。
x = sizeof(char); //x 的值是1,因为 char 是一个字节大小
注:sizeof 的返回值是编译时常量,所以在程序运行之前就确定了。
参考 cplusplus
c++ 提供了一些流对象能够处理字符序列。
流对象 | 描述 |
---|---|
cin | 标准输入流 |
cout | 标注输出流 |
cerr | 标注错误输出流 |
clog | 标准日志输出流 |
示例:
cout << "hello" << " world\n";
string str = "hello";
cout << str << " world" << endl;
//endl 除了起到换行的作用外,还会将缓冲区的流刷到输出设备上,
//频繁的请求输出设备可能会引起延迟或过载等风险。
示例:
cin >> a >> b;
//以上等于
cin >> a;
cin >> b;
对于字符串的输入,为了保留空格或空行,可以使用 string
库中的 getline
函数替代 cin
。
示例:
// cin with strings
#include
#include
using namespace std;
int main ()
{
string mystr;
cout << "What's your name? ";
getline (cin, mystr);
cout << "Hello " << mystr << ".\n";
cout << "What is your favorite team? ";
getline (cin, mystr);
cout << "I like " << mystr << " too!\n";
return 0;
}
为了方便将字符串转换成其他数字类型,可以使用 sstream
库中的 stringstream
函数。
示例:
// stringstreams
#include
#include
#include
using namespace std;
int main ()
{
string mystr;
float price=0;
int quantity=0;
cout << "Enter price: ";
getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: ";
getline (cin,mystr);
stringstream(mystr) >> quantity;
cout << "Total price: " << price*quantity << endl;
return 0;
}