本文主要是介绍type 相关的几个试验,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.概要
typeid
是一个操作符,它用于在运行时获取关于数据类型的信息。
在C语言中,类型定义(Type Definition)通常是通过使用关键字如 typedef
来创建新的类型名称(也称为类型别名),这些新的类型名称可以代表已存在的数据类型、结构体(struct
)、联合体(union
)或枚举(enum
)等。
2.代码
#include <iostream>
using namespace std;//typeid试验
namespace test1 {class A{};void main() {const type_info& type = typeid(A);cout << type.name() << endl;}
}
//typedef试验
namespace test2 {//的应用场景有哪些typedef int myInt;typedef int (*My_fun)(int a, int b);int fun(int a, int b) {return a + b;}void main() {myInt a = 5;My_fun f = fun;int c = f(3, 5);cout << c << endl;}
}
//sizeof试验
namespace test3 {class A{};class B{int a;};class C{int a;int b;};class D{int a;int b;int fun(int a, int b) {return a + b;}};void main() {int a = 5;int b = sizeof(a);cout << b << endl;b = sizeof(A);cout << b << endl;b = sizeof(B);cout << b << endl;b = sizeof(C);cout << b << endl;b = sizeof(D);cout << b << endl;}
}
int main()
{test1::main();test2::main();test3::main();cout << "Hello World!\n";
}
3.运行结果
class test1::A
8
4
1
4
8
8
Hello World!
4.补充
1.c typeid
在C++中,typeid
是一个操作符,它用于在运行时获取关于数据类型的信息。这是C++的RTTI(运行时类型识别)机制的一部分。typeid
可以返回一个type_info
对象的引用,该对象封装了有关数据类型的信息。
以下是一些关于typeid
的要点:
-
用法:
typeid(expression)
或typeid(type-name)
expression
是一个表达式,其类型将被确定。type-name
是一个类型名称(如int
,MyClass
等)。
-
注意:
typeid
只能用于多态上下文中的指针或引用。如果你对一个非多态类型或值使用typeid
,它将直接返回该类型的type_info
,而不会进行任何动态解析。 -
与
dynamic_cast
一起使用:在多态环境中,typeid
和dynamic_cast
通常一起使用来确保类型转换的安全性。 -
示例:
#include <iostream> | |
#include <typeinfo> | |
class Base { | |
public: | |
virtual ~Base() {} | |
}; | |
class Derived : public Base {}; | |
int main() { | |
Base* basePtr = new Derived(); | |
// 使用 typeid 检查指针所指向的对象的实际类型 | |
if (typeid(*basePtr) == typeid(Derived)) { | |
std::cout << "It's a Derived object!" << std::endl; | |
} else { | |
std::cout << "It's not a Derived object!" << std::endl; | |
} | |
delete basePtr; | |
return 0; | |
} |
在这个示例中,由于Base
有一个虚析构函数(使其成为多态类型),所以我们可以使用typeid
来检查basePtr
实际指向的对象类型。
但是,如果你尝试对不是通过指针或引用访问的多态类型使用typeid
,它将不会返回你期望的结果,因为它不会进行动态类型解析。
2.typeid的返回值是啥
typeid
操作符在C++中返回一个对std::type_info
对象的引用,该对象封装了有关数据类型的信息。std::type_info
是一个在<typeinfo>
头文件中定义的类,它包含了关于数据类型(如名称、是否是指针或引用等)的元信息。
std::type_info
类的主要用途是允许程序在运行时查询有关数据类型的信息,但请注意,这个信息通常不包括类型的完整名称(例如,它不会返回如"int"
或"MyClass"
这样的字符串),而是返回一个能够唯一标识类型的内部标识符。
你可以使用std::type_info
的成员函数name()
来获取类型的名称,但返回的字符串格式是特定于实现的,并且可能不是人类可读的。通常,这个字符串主要用于调试和诊断目的,而不是用于显示给用户。
此外,std::type_info
还提供了operator==()
和operator!=()
来比较两个类型信息对象是否相同。
下面是一个简单的示例,展示了如何使用typeid
和std::type_info
:
#include <iostream> | |
#include <typeinfo> | |
int main() { | |
int a = 0; | |
double b = 0.0; | |
// 获取a和b的类型信息 | |
const std::type_info& info_a = typeid(a); | |
const std::type_info& info_b = typeid(b); | |
// 输出类型信息的名称(但注意这可能是编译器特定的) | |
std::cout << "Type of a: " << info_a.name() << std::endl; | |
std::cout << "Type of b: " << info_b.name() << std::endl; | |
// 比较两个类型信息对象是否相同 | |
if (info_a == info_b) { | |
std::cout << "a and b are of the same type." << std::endl; | |
} else { | |
std::cout << "a and b are of different types." << std::endl; | |
} | |
return 0; | |
} |
在这个示例中,info_a.name()
和info_b.name()
将输出编译器特定的类型名称字符串,这些字符串可能不是人类可读的。而类型比较将正确地指出a
和b
是不同类型的。
3.c 类型定义
在C语言中,类型定义(Type Definition)通常是通过使用关键字如 typedef
来创建新的类型名称(也称为类型别名),这些新的类型名称可以代表已存在的数据类型、结构体(struct
)、联合体(union
)或枚举(enum
)等。
使用 typedef
定义类型别名
typedef
关键字用于为已有的数据类型定义一个新的名称。这可以使代码更易于阅读和维护,特别是当使用复杂的数据类型时。
示例 1:为整数类型定义别名
typedef int Integer; | |
Integer a = 10; // 相当于 int a = 10; |
示例 2:为结构体定义别名
typedef struct { | |
int x; | |
int y; | |
} Point; | |
Point p; // 创建一个Point类型的变量p | |
p.x = 10; | |
p.y = 20; |
结构体(Struct)
结构体是一种复合数据类型,允许你将多个不同类型的数据组合成一个单一的类型。
struct Person { | |
char name[50]; | |
int age; | |
}; | |
struct Person person1; // 创建一个Person类型的变量person1 | |
strcpy(person1.name, "Alice"); | |
person1.age = 30; |
联合体(Union)
联合体是一种特殊的数据结构,允许你在相同的内存位置存储不同的数据类型。但是,在任何时候,联合体只能存储其中一种类型的数据。
union Data { | |
int i; | |
float f; | |
char str[20]; | |
}; | |
union Data data; | |
data.i = 10; // 现在data存储一个整数 | |
// ... | |
data.f = 220.5; // 现在data存储一个浮点数,之前存储的整数被覆盖 |
枚举(Enum)
枚举是一种用户定义的数据类型,它包含一组命名的整数值。默认情况下,枚举中的第一个枚举符的值为0,后面每个枚举符的值比前一个枚举符的值大1。但是,你也可以显式地为枚举符指定整数值。
enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat }; | |
enum Days today = Mon; // today的值为1(假设Sun的值为0) |
4.c 判断一个变量的类型
在C语言中,与C++的typeid
操作符不同,没有直接的方式来查询一个变量的类型并在运行时输出其类型名称。但是,你可以通过编写一些宏或函数来模拟这种功能,尽管这些方法通常不如C++中的typeid
那样强大和灵活。
一种常见的方法是使用_Generic
关键字(在C11及更高版本中可用),它允许你根据表达式的类型来选择不同的结果。但是,_Generic
主要用于在编译时基于类型做出决策,而不是在运行时查询类型。
不过,你可以通过创建一些宏来模拟类型检查,但这些宏通常只能用于有限的一组类型,并且不能提供完整的类型名称。以下是一个简单的示例,该示例展示了如何使用宏来检查一个变量是否为整数类型:
#include <stdio.h> | |
#define IS_INT(x) _Generic((x), int: 1, default: 0) | |
int main() { | |
int a = 5; | |
float b = 3.14; | |
if (IS_INT(a)) { | |
printf("a is an integer.\n"); | |
} else { | |
printf("a is not an integer.\n"); | |
} | |
if (IS_INT(b)) { | |
printf("b is an integer.\n"); | |
} else { | |
printf("b is not an integer.\n"); | |
} | |
return 0; | |
} |
在这个例子中,IS_INT
宏使用_Generic
来检查其参数是否为int
类型。如果是,则返回1;否则返回0。然后,你可以根据这个宏的返回值来编写条件语句。
但是,请注意这种方法只能用于有限的一组类型,并且不能用于检查所有可能的类型。此外,它也不能提供关于类型的完整信息(如类型名称)。
如果你需要在C语言中实现更复杂的类型检查或类型信息获取功能,你可能需要考虑使用其他编程语言或工具,或者设计一种适合你特定需求的解决方案。在某些情况下,你可能需要手动跟踪和管理类型信息,以便在运行时使用。
这篇关于type 相关的几个试验的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!