前言
在 C++ 语法体系中,存在大量形态简短、多重语义的符号。很多符号外观相同,但是处在不同上下文时代表完全不同的功能,例如::、:、.、->、*、&、<>等,是 C++ 入门阶段最容易混淆,同时也是笔试、面试高频考察内容。C 语言基础只覆盖基础算术、位运算,而 C++ 扩展出作用域符号、成员访问、模板标记、lambda 捕获、初始化列表、三元运算符、右值引用、范围 for 冒号等全新语法符号。
不少开发者长期只凭经验使用各类符号,分不清运算符优先级、不同场景下符号语义差异,极易产生隐蔽 BUG:比如混淆.和->、区分不开取地址&与引用&、误把==写成=、看不懂模板<>、无法分辨左值引用与右值引用&&。
本文将按照功能对 C++ 所有常用符号、运算符进行系统性归类讲解,区分语法标记符与运算符,每个知识点配备可直接编译运行的代码示例,辨析易错场景、相似符号对比
一、作用域与归属标记符号
1.1 作用域解析运算符 ::
:: 是 C++ 独有的运算符,名称:作用域解析运算符。核心功能:明确指定标识符所属作用域,打破局部名字遮蔽,区分全局、命名空间、类作用域。 适用场景:访问全局变量、命名空间成员、类静态成员、定义类外成员函数。
示例 1:区分局部变量与全局变量
#include <iostream>
using namespace std;
int data = 100; // 全局变量
int main()
{
int data = 10; // 局部变量遮蔽全局变量
cout << "局部data = " << data << endl;
cout << "全局data = " << ::data << endl; // ::直接访问全局作用域
return 0;
}
示例 2:命名空间访问
#include <iostream>
namespace CustomNs
{
void func()
{
std::cout << "自定义命名空间函数执行" << std::endl;
}
int val = 888;
}
int main()
{
CustomNs::func();
std::cout << CustomNs::val << std::endl;
return 0;
}
示例 3:类外部定义成员函数、访问静态成员
#include <iostream>
using namespace std;
class Demo
{
public:
static int num;
void show();
};
// 类外定义成员函数:类名::函数名
void Demo::show()
{
cout << "类外部实现的成员函数" << endl;
}
// 静态成员初始化
int Demo::num = 66;
int main()
{
Demo d;
d.show();
cout << Demo::num << endl;
return 0;
}
1.2 单冒号 :(多重语义,极易混淆)
: 不属于运算符,属于语法分隔标记,在四种场景拥有完全不同含义:
- 类继承定义
- 构造函数初始化列表
- 三目运算符
?: - C++11 范围 for 循环
示例 1:继承语法
#include <iostream>
using namespace std;
class Base{};
// : 表示继承关系,public为继承方式
class Son : public Base
{
};
int main()
{
Son s;
return 0;
}
示例 2:构造函数初始化列表
#include <iostream>
#include <string>
using namespace std;
class Person
{
private:
int age;
string name;
public:
// : 后跟随初始化列表,优先于构造函数体执行
Person(int a, string n): age(a), name(n)
{
cout << name << "," << age << endl;
}
};
int main()
{
Person p(20, "小明");
return 0;
}
示例 3:范围 for 循环 C++11
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec{1,2,3,4,5};
// : 分隔变量与容器
for(auto v : vec)
{
cout << v << " ";
}
return 0;
}
示例 4:三元运算符 条件 ? 表达式1 : 表达式2
#include <iostream>
using namespace std;
int main()
{
int a = 10, b = 20;
int maxVal = a > b ? a : b;
cout << maxVal << endl;
return 0;
}
二、成员访问符号 . 与 ->
二者功能都是访问类 / 结构体成员,使用场景严格区分:
.:对象实例(栈对象、引用)访问成员->:指针访问对象成员;ptr->member等价于(*ptr).member
示例对比:
#include <iostream>
using namespace std;
struct Student
{
int id;
void print()
{
cout << "学号:" << id << endl;
}
};
int main()
{
Student s;
s.id = 1001;
s.print(); // 对象 . 成员
Student* p = &s;
p->id = 1002;
p->print(); // 指针 -> 成员
(*p).id = 1003;
(*p).print();
Student& ref = s;
ref.id = 1004;
ref.print(); // 引用使用 .
return 0;
}
常见错误:对象使用
->、指针使用.,编译直接报错。
三、星号 * 多重语义
* 根据上下文拥有四种核心含义:乘法运算符、指针声明、解引用、函数指针。
-
算术乘法:
a * b -
指针类型标记:
int* p -
解引用运算符:
*p,取出指针指向内存的值#include
using namespace std;int main()
{
// 1.乘法运算
int a = 3 * 5;
cout << a << endl;int num = 100; // 2.指针声明 int* p = # // 3.解引用 cout << *p << endl; *p = 200; cout << num << endl; return 0;}
四、& 符号多重语义
& 三种用途:按位与运算符、取地址运算符、引用声明(C++ 独有)
-
a & b:按位与运算 -
&val:取变量内存地址 -
int& ref:左值引用声明#include
using namespace std;int main()
{
// 按位与
int x = 6 & 3;
cout << "6 & 3 = " << x << endl;int num = 10; // 取地址 int* p = # cout << "num地址:" << p << endl; // 左值引用 int& ref = num; ref = 999; cout << num << endl; return 0;}
拓展:&& 双重与,两种语义
-
a && b逻辑与运算符(短路运算) -
int&& rref右值引用(C++11)#include
using namespace std;void func(int&& r)
{
cout << "右值引用接收:" << r << endl;
}int main()
{
// 逻辑与
bool res = (10 > 5) && (3 > 1);
cout << res << endl;func(500); // 传入临时右值 return 0;}
五、模板尖括号 <>
<> 是模板语法标记,不属于比较运算符。用于类模板、函数模板声明与实例化。 区分:a < b 是小于运算符;Template<Type> 是模板参数列表。
#include <iostream>
#include <vector>
using namespace std;
// 函数模板
template<typename T>
T maxNum(T a, T b)
{
return a > b ? a : b;
}
int main()
{
cout << maxNum<int>(11,22) << endl;
vector<int> vec; // vector<int> <>包裹模板参数
return 0;
}
C++11 语法坑:
>>在模板末尾,旧标准必须空格vector<vector<int> >;C++11 开始支持vector<vector<int>>。
六、移位运算符 <<>>
两种语义:
-
位运算:左移
<<、右移>> -
流运算符(C++ 重载):
cout <<、cin >>#include
using namespace std;int main()
{
// 位运算左移
int a = 1 << 3;
cout << "1 << 3 = " << a << endl;// 流输出运算符 cout << "测试输出" << endl; int input; cin >> input; return 0;}
七、括号系列符号 () [] {}
7.1 圆括号 ()
- 函数调用、函数声明
func() - 表达式优先级调整
(a+b)*c - 强制类型转换
(int)val - 值初始化
int num(10)
7.2 方括号 []
- 数组下标访问
arr[0] - operator \[\] 重载
- lambda 捕获:
[=][&]
7.3 大括号 {} C++11 统一初始化列表
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// 统一列表初始化
int a{100};
int arr[]{1,2,3};
vector<int> v{5,6,7};
// lambda表达式 []捕获 ()参数 {}函数体
auto lambda = [](int x){
cout << x << endl;
};
lambda(99);
return 0;
}
八、关系、逻辑运算符
== 等于 ;!=不等于;> < >= <= 逻辑:&&逻辑与,||逻辑或,!逻辑非 重点区分:=赋值运算符,==比较相等,新手高频错误。
#include <iostream>
using namespace std;
int main()
{
int a = 10;
if (a == 10) // 判断相等
{
cout << "相等" << endl;
}
// if(a=20) 是赋值,永远成立,隐蔽BUG
return 0;
}
九、位运算符汇总
~按位取反、&按位与、|按位或、^按位异或、<<左移、>>右移
#include <iostream>
using namespace std;
int main()
{
int x = 5; // 0101
int y = 3; // 0011
cout << (x & y) << endl;
cout << (x | y) << endl;
cout << (x ^ y) << endl;
return 0;
}
十、赋值复合运算符
=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=
#include <iostream>
using namespace std;
int main()
{
int num = 10;
num += 5;
num *= 2;
cout << num << endl;
return 0;
}
十一、自增自减运算符 ++ --
前置 ++a、后置a++;-- 同理。 前置:先自增,返回自增后值(左值) 后置:先返回原值,再自增(右值)
#include <iostream>
using namespace std;
int main()
{
int a = 10;
cout << a++ << endl; //输出10
cout << ++a << endl; //输出12
return 0;
}
十二、Lambda 表达式专用符号
[]捕获列表、()参数、mutable、->尾随返回类型 语法格式:[捕获](参数) -> 返回类型 {函数体}
#include <iostream>
using namespace std;
int main()
{
int num = 100;
// -> 指定lambda返回值类型
auto func = [num](int x) -> int{
return num + x;
};
cout << func(20) << endl;
return 0;
}
十三、其它特殊符号
13.1 . 点号与 .*、->*
成员指针运算符,日常使用较少,用于类成员指针访问:
#include <iostream>
using namespace std;
class Test
{
public:
int val = 666;
};
int main()
{
Test t;
int Test::*p = &Test::val;
cout << t.*p << endl;
Test* pt = &t;
cout << pt->*p << endl;
return 0;
}
13.2 逗号运算符 ,
逗号表达式,从左向右执行,返回最右侧结果
#include <iostream>
using namespace std;
int main()
{
int a = (1+2, 3+4, 10);
cout << a << endl; //输出10
return 0;
}
13.3 单引号 ' ' 字符常量;双引号 " " 字符串字面量
char ch = 'A';
const char* str = "hello";
13.4 注释符号
//单行注释;/* */块注释
十四、极易混淆符号对照表总结
::作用域解析 |.对象成员访问 |->指针成员访问&:引用 / 取地址 / 按位与 |&&:逻辑与 / 右值引用*:乘法 / 指针 / 解引用=赋值 |==判断相等<比较小于 |<>模板参数包裹<<左移运算 /cout 输出:多种语法标记 |?:三目运算符
十五、综合易错知识点总结
- 符号语义依赖上下文,不存在绝对固定含义,不能死记单一功能;
- 区分运算符优先级:
()>++/*/&> 算术运算 > 比较运算 > 逻辑运算 >=赋值;复杂表达式尽量加括号消除歧义; - 不要混淆对象
.与指针->,是新手最高频编译错误; &与*在声明和表达式中含义完全不同;&&兼具逻辑运算与右值引用两种无关语义,不要互相混淆;- 模板
<>和比较运算符<仅仅外观一致,语法层级完全无关; - 逗号运算符极易被忽视,在循环、赋值语句容易产生预期之外结果;
- 区分初始化列表
{}、函数调用()、数组[]三类括号使用场景。