C++选择操作全解析
立即解锁
发布时间: 2025-08-16 01:31:05 阅读量: 14 订阅数: 73 


C++编程语言精解:从基础到高级特性
### C++ 操作符与编程技巧详解
#### 1. 各类操作符
在 C++ 编程中,有多种操作符可供使用,下面为你详细介绍:
- **逻辑操作符**:逻辑操作符包括 &&(逻辑与)、||(逻辑或)和 !(逻辑非)。它们接受算术和指针类型的操作数,将其转换为 bool 类型,并返回 bool 结果。&& 和 || 操作符仅在必要时计算第二个参数,可用于控制求值顺序。示例代码如下:
```cpp
while (p && !whitespace(*p)) ++p;
```
在上述代码中,如果 p 为 nullptr,则不会对其进行解引用操作。
- **位逻辑操作符**:位逻辑操作符有 &(按位与)、|(按位或)、^(按位异或)、~(按位取反)、>>(右移)和 <<(左移),这些操作符应用于整数类型的对象。位逻辑操作符常用于实现小集合(位向量)的概念,例如:
```cpp
enum ios_base::iostate {
goodbit=0, eofbit=1, failbit=2, badbit=4
};
state = goodbit;
if (state&(badbit|failbit)) // stream not good
```
这里,& 表示交集,| 表示并集,^ 表示对称差,~ 表示补集。
- **条件表达式**:条件表达式可以方便地替代一些 if 语句,例如:
```cpp
max = (a<=b) ? b : a;
```
条件表达式可用于常量表达式,两个表达式 e1 和 e2 作为条件表达式 c?e1:e2 的替代时,需满足一定条件。
- **自增和自减操作符**:++ 操作符用于直接表达递增,-- 操作符用于递减。它们可作为前缀和后缀操作符使用,示例代码如下:
```cpp
void cpy(char* p, const char* q)
{
while (*p++ = *q++) ;
}
```
#### 2. 自由存储区
自由存储区允许创建独立于创建范围而存在的对象,通过 new 操作符创建对象,delete 操作符销毁对象。
- **对象创建与销毁**:使用 new 创建对象,示例如下:
```cpp
struct Enode {
Token_value oper;
Enode* left;
Enode* right;
// ...
};
Enode* expr(bool get)
{
Enode* left = term(get);
for (;;) {
switch (ts.current().kind) {
case Kind::plus:
case Kind::minus:
left = new Enode {ts.current().kind,left,term(true)};
break;
default:
return left;
}
}
}
```
使用 delete 销毁对象:
```cpp
void generate(Enode* n)
{
switch (n->oper) {
case Kind::plus:
delete n;
}
}
```
- **内存管理问题**:自由存储区存在一些常见问题,如对象泄漏、过早删除和双重删除。为避免这些问题,可采用以下两种方法:
- 尽量不使用自由存储区,优先使用作用域变量。
- 将对象指针放入具有析构函数的管理对象中,遵循 RAII 原则。
例如,标准库的 vector 就是一个很好的例子:
```cpp
void f(const string& s)
{
vector<char> v;
for (auto c : s)
v.push_back(c);
// ...
}
```
- **获取内存空间**:自由存储区操作符 new、delete、new[] 和 delete[] 通过 <new> 头文件中的函数实现。当 new 无法分配存储时,默认会抛出 std::bad_alloc 异常。示例代码如下:
```cpp
void f()
{
vector<char*> v;
try {
for (;;) {
char *p = new char[10000];
v.push_back(p);
p[0] = 'x';
}
}
catch(bad_alloc) {
cerr << "Memory exhausted!\n";
}
}
```
- **重载 new 操作符**:可以通过提供带有额外参数的分配器函数来重载 new 操作符,实现对象在不同位置的分配。示例如下:
```cpp
void* operator new(size_t, void* p) { return p; }
void* buf = reinterpret_cast<void*>(0xF00F);
X* p2 = new(buf) X;
```
#### 3. 列表
{}-列表除了用于初始化命名变量外,还可作为表达式在许多地方使用,有两种形式:
- **限定列表**:限定列表的形式为 T{...},表示创建一个由 T{...} 初始化的类型为 T 的对象。示例如下:
```cpp
struct S { int a, b; };
void f()
{
S v {7,8};
v = S{7,8};
S* p = new S{7,8};
}
```
- **非限定列表**:非限定列表 {...} 的类型需根据使用上下文确定,可作为函数参数、返回值、赋值操作符的右操作数和下标使用。示例如下:
```cpp
int f(double d, Matrix& m)
{
int v {7};
int v2 = {7};
int v3 = m[{2,3}];
v = {8};
v += {88};
f({10.0});
return {11};
}
```
#### 4. 列表实现模型
{}-列表的实现模型分为以下三个部分:
|实现情况|具体说明|
| ---- | ---- |
|作为构造函数参数|实现方式如同使用 ()-列表,列表元素除非作为按值传递的构造函数参数,否则不会被复制|
|初始化聚合元素|每个列表元素初始化聚合的一个元素,列表元素除非作为按值传递的聚合元素构造函数参数,否则不会被复制|
|构造 initializer_list 对象|每个列表元素用于初始化 initia
0
0
复制全文
相关推荐









