1.20 Typedef 为已有的类型取别名
1.typedef语法格式
在 C++ 中,可以使用 typedef
关键字来为已有的类型创建一个别名。这对于提高代码可读性、简化类型声明以及增加代码的可维护性非常有用。
下面是 typedef
的语法格式:
typedef 旧类型名 别名;
2.使用typedef为已有类型取别名
示例展示了如何使用 typedef
为已有的类型创建别名:
typedef int MyInt; // 将 int 类型命名为 MyInt
typedef double Distance; // 将 double 类型命名为 Distance
typedef char* CString; // 将 char* 类型命名为 CString
typedef void (*FuncPtr)(int); // 将函数指针类型命名为 FuncPtr
typedef struct {
int x;
int y;
} Point; // 将匿名结构体定义为名为 Point 的类型
typedef std::vector<int> IntVector; // 将 std::vector<int> 类型命名为 IntVector
通过为已有类型创建别名,我们可以使用别名来声明变量、函数参数、返回值类型等,这样可以增加代码的可读性和易于理解性。例如:
MyInt num = 42; // 使用别名 MyInt 声明变量
Distance dist = 3.14; // 使用别名 Distance 声明变量
void PrintString(CString str) {
// 使用别名 CString 定义函数参数
// ...
}
FuncPtr func = nullptr; // 使用别名 FuncPtr 声明函数指针变量
Point p; // 使用别名 Point 声明结构体变量
IntVector vec; // 使用别名 IntVector 声明向量容器变量
3.typedef使用步骤
注意:不能创建新类型,实际上就是将长且复杂的类型名,取一个精简的类型名。
typedef作用的步骤
1、先用已有的数据类型定义一个普通的变量
2、用新的别名替换原变量名
3、在整个表达式最前方加关键字:typedef
1.案例,将int arr[3];取别名
int arr[3]; //第一步 找到你需要取别名的类型
typedef int num[3];//取别名
num arr;//用新的别名创建一个arr
1.21 转义字符
1. \和某些字符 结合 产生新的字符含义 就叫转义字符
0== ASCII 为0
== 换行符n'
t'== tab缩进符
r==回到行首符号
==发出警报a'
2 八进制转义
ddd’每个d的范围必须是0-7 3个d表示最多识别3位八进制数据以下字符描述正确的是 A
A: 123' B:18 C:' 1234' D:183
3 十六进制转义
\xhh'每个h的范围0-9 a-f 2个h表示最多识别2位十六进制以下字符描述正确的是 BD
A:' af' B:' 123' C: x3df' D: xab
4.常见的转义字符符号
在 C++ 中,转义字符用于表示一些特殊字符,它们以反斜线 \
开始,并在后面跟着一个字符。下面是一些常见的 C++ 转义字符:
\\
:反斜线\'
:单引号\"
:双引号\n
:换行符\r
:回车符\t
:制表符\b
:退格符\f
:换页符\a
:警报符(输出提示音)\v
:垂直制表符\0
:空字符(以 NUL 字符表示)
这些转义字符可以嵌入到字符串常量中,以表示特定的字符或执行特定的操作。例如:
cout << "Hello\tWorld\n"; // 输出:Hello World(使用制表符和换行符)
cout << "She said, \"Hello!\"\n"; // 输出:She said, "Hello!"(使用双引号)
cout << "C:\\Program Files\\MyApp\n"; // 输出:C:\Program Files\MyApp(使用反斜线)
cout << "Beep!\a\n"; // 输出:Beep!(并发出警报音)
需要注意的是,在 C++11 及更高版本中,还引入了一种称为原始字符串字面量 (raw string literals) 的特殊语法,可以避免使用转义字符。原始字符串字面量以 R"(" 和 ")“ 开始和结束,并且可以在其中包含任何字符而不需要转义。例如:
cout << R"(This is a raw string literal containing "double quotes" and \backslashes\.)" << endl;
// 输出:This is a raw string literal containing "double quotes" and \backslashes\.
1.22 类型转换
C++ 中的类型转换(Type Casting)是将一个数据类型的值转换为另一个数据类型的过程。类型转换可以通过显式转换(Explicit Casting)和隐式转换(Implicit Casting)来实现。数据有不同的类型,不同类型数据之间进行混合运算时必然涉及到类型的转换问题转换的方法有两种
1. 隐式转换(Implicit Casting)
隐式转换是指在不需要显式指定的情况下自动进行的类型转换。它发生在以下情况下:
当一个表达式中包含不同类型的操作数时,编译器会自动执行类型提升或类型转换以匹配操作数的类型。例如,将整数和浮点数相加时,整数会被隐式转换为浮点数。
当调用函数时,如果传递的实参的类型与形参的类型不完全匹配,但是可以通过隐式转换实现匹配,编译器也会自动进行类型转换。
自动转换:
遵循一定的规则,由编译系统自动完成强制类型转换。
2. 显式转换(Explicit Casting)强制类型转换
显式转换是指将类型转换操作显式地指定在代码中的过程。它可以通过 C++ 中提供的四种转换操作符来实现:(智能指针)
static_cast:用于执行任意合理的类型转换,如数值类型之间的转换、指针类型之间的转换、向上或向下转换等。
reinterpret_cast:用于进行底层的重新解释转换,将一个对象的二进制表示解释为另一种类型。这种转换通常非常危险,需要谨慎使用。
const_cast:用于去除变量的常量性或增加变量的常量性。
dynamic_cast:用于在继承关系中的向上转型和向下转型。它进行类型检查,并在运行时检测转换的有效性。
需要注意的是,类型转换应该谨慎使用,确保转换的类型是兼容的,以避免数据的丢失或无效的转换。隐式转换的过多使用可能会导致代码可读性降低,因此建议在需要转换类型的地方使用显式转换符来明确指定转换操作。在进行类型转换操作时,应该理解转换的操作和可能带来的影响,并遵循最佳实践。
例如:
int a = 10;
double b = static_cast<double>(a); // 隐式转换为浮点数
char c = static_cast<char>(b); // 显式转换为字符
int* ptr1 = reinterpret_cast<int*>(a); // 重新解释为指针
const int* ptr2 = const_cast<const int*>(ptr1); // 去除指针的常量性
Base* base = new Derived();
Derived* derived = dynamic_cast<Derived*>(base); // 向下转型,进行类型检查
3.转换原则
-
数字类型之间的转换
- 小范围整数类型可以自动转换为大范围整数类型,例如将
int
赋值给long
。 - 整数类型可以自动转换为浮点数类型,例如将
int
赋值给double
。 - 浮点数类型可以自动转换为整数类型,但可能会导致小数部分被截断,例如将
double
赋值给int
。
-
数组和指针之间的转换:
- 数组名可以自动转换为指向数组首元素的指针。
- 指向派生类的指针可以自动转换为指向基类的指针(向上转型),但相反的转换需要显式的类型转换。
-
枚举类型和整数类型之间的转换:
- 枚举类型可以自动转换为整数类型,例如将枚举变量赋值给
int
。
- 枚举类型可以自动转换为整数类型,例如将枚举变量赋值给
-
布尔类型和整数类型之间的转换:
false
被视为整数0
,true
被视为整数1
。
-
const
限定符的转换:const
限定符可以通过const_cast
进行去除,允许对变量进行修改。const
限定符不能通过直接赋值的方式去除,除非使用const_cast
进行显式转换。
需要注意的是,默认类型转换只适用于满足一定条件的类型,并且转换可能会导致精度损失或数据截断。对于不同类型之间的转换,应该谨慎考虑可能带来的副作用,并在需要的情况下使用显式类型转换。
该图片引用了千锋教育C++课程中对转换关系方向解释的图例,主要是展示了转换的方向。