华亭网站建设,网站维护与推广定义,网页制作与网站建设,游戏开发app类型别名
在C中#xff0c;我们可以使用typedef关键字或using关键字来创建类型别名。下面是两种方式的示例#xff1a;
使用typedef关键字创建类型别名#xff1a;
typedef int myInt;
typedef float myFloat;myInt a;//等价int a;
myFloat b;//等价float b; 使用using关…类型别名
在C中我们可以使用typedef关键字或using关键字来创建类型别名。下面是两种方式的示例
使用typedef关键字创建类型别名
typedef int myInt;
typedef float myFloat;myInt a;//等价int a;
myFloat b;//等价float b; 使用using关键字创建类型别名
using myInt int;
using myFloat float;myInt a;//等价int a;
myFloat b;//等价float b;使用类型别名可以方便地重命名现有的类型以提高代码的可读性和灵活性。例如我们可以使用以下方式创建一个类型别名来代替std::vectorint
using IntVector std::vectorint;
IntVector myVector;注意点
我们在使用类型别名的时候要特别注意将类型别名用于指针
我们先看个例子 我们发现啊这个第二行这句还没编译就已经显示有错误了这是为什么呢
这是因为遇到使用类型别名的声明语句的时候人们总是错误的尝试把类型别名替换为它本来的样子也就是说我们把这下面两句话视作等效的
const A basss;
const char*basss;
但是事实并不是如此。
A实际上是指向char的指针因此const A就是指向char的常量指针而非指向常量字符的指针。
也就是说下面这两句是等效的 const A b asss;;char* const a asss;
我们再总结一下 声明语句中用到A时其基本数据类型是指针。
可是用char*重写了声明语句后数据类型就变成了char*成了声明符的一部分。这样改写的结果是const char成了基本数据类型
前后两种声明意义截然不同前者声明了一个指向char的常量指针改写后的形式则声明了一个指向const char的指针
关键字auto
在C中关键字auto用于自动推导变量的类型。也就是说编译器会根据变量的初始化值来确定变量的类型。
显然auto定义的变量必须要有初始值。
定义的具体语法如下
auto variable value;其中variable是变量名value是初始化值。
例如以下是使用auto定义变量的示例
auto x 10; // 推导x的类型为int初始化为10
auto str Hello; // 推导str的类型为const char*
auto vec std::vectorint(); // 推导vec的类型为std::vectorint
auto sum [](int a, int b) { return a b; }; // 推导sum的类型为lambda表达式类型
在这些例子中编译器会根据变量的初始化值自动推导出变量的类型并将其赋值给相应的变量。
使用auto也可以在一条语句中声明多个变量。因为一条声明语句只能有一个基本数据类型所以该语句中所有变量的初始数据类型都必须一样
int a9;
auto i0,*pa;//正确i是int型p是int*型
auto b0,c9.0;//不正确b和c的类型不正确
复合类型常量和auto
编译器推断出来的auto类型有时候和初始值的类型并不完全一样编译器会适当地改变结果类型使其更符合初始化规则。
第一点
首先正如我们所熟知的使用引用其实是使用引用的对象特别是当引用被用作初始值时真正参与初始化的其实是引用对象的值。
此时编译器以引用对象的类型作为auto的类型
int i0,ri;
auto ar;//a是一个整数r是i的别名,而i是一个整数 也就是说上面这些语句就等价于下面这个
int i0,ri;
int ai;
解决方法
那我们怎么使用auto来用于引用呢
很简单直接在auto后面加一个就行了
int i0,ri;
auto ai;
第二点
auto一般会忽略掉顶层const同时保留底层const
什么意思呢我们来看看一些例子
例子1 int i 9;const int ci i, cr ci;auto b ci;//等价int bi;auto c cr;//等价int ci;我们可能会好奇
为啥b不是const int类型c为啥不是const int类型?
因为ci的顶层const特性被忽略掉了 c也是同样的道理
如果我们需要将bc保留顶层const特性则需要明确指出 int i 9;const int ci i, cr ci;const auto b ci;//等价const int bi;const auto c cr;//等价const int ci; 例子2
我们再看一个例子
int i 9;
const int ci i, cr ci;
auto d i;//等价int* di;
auto e ci;//等价const int*eci; 那为啥e就是const int*类型
这是因为对常量对象取地址是一种底层const会被保留下来
注意事项
以下是一些关于auto关键字的注意事项 auto只能用于自动推导变量的类型不能用于函数的返回值、函数参数或非静态成员变量的类型。 自动推导的类型将根据变量的初始化值进行推导。如果变量的初始化值不明确或不唯一编译器将会报错。 auto关键字可以与const、等类型修饰符一起使用。例如auto const表示自动推导一个const引用。 当使用auto推导出的类型是一个模板类型时编译器会根据变量的初始化值推导出具体的模板类型。 当使用auto推导出的类型是迭代器时需要确保变量的初始化值是一个可迭代的容器否则会导致编译错误。 自动推导类型的变量在编译时期确定类型无法在运行时期更改类型。
总而言之auto关键字是一个方便的特性可以根据初始化值自动推导变量的类型减少了显式类型声明的冗余。但需要注意过度使用auto可能会降低代码的清晰度和可读性所以在选择使用auto时要谨慎权衡代码的简洁性和可读性。 关键字decltype
有的时候我们希望从表达式的类型推断出要定义的变量的类型但是不是想用该表达式的值初始化变量。
为了满足这种情况C11引入了关键字decltype它的作用是选择并返回操作数的数据类型。在此过程中编译器分析表达式并得到它的类型却不实际计算表达式的值。
我们看个例子
decltype(f()) sumx;//sum的类型就是f()返回值的类型
编译器并不实际调用函数f而是使用当调用发生时f的返回值类型作为sum的类型。
换句话说编译器为sum指定的类型是什么呢就是假如f被调用的话将会返回的那个类型。 decltype和顶层const引用
decltype处理顶层const和引用的方式与auto有些许不同。
如果decltype使用的表达式是一个变量则decltype返回该变量的类型(包括顶层const 和引用在内)
const int ci 0, cjci;
decltype(ci)x0; //x的类型是const int
decltype(cj) y x; //y的类型是const intsy绑定到变量x
decltype(cj)z; //错误z是一个引用必须初始化 因为cj是一个引用decltype(cj)的结果就是引用类型因此作为引用的z必须被初始化。
需要指出的是引用从来都作为其所指对象的同义词出现只有用在decltype处是一个例外,decltype直接给一个引用类型 decltype 和引用
如果decltype使用的表达式不是一个变量则decltype返回表达式结果对应的类型。
有些表达式将向decltype返回一个引用类型。
一般来说当这种情况发生时意味着该表达式的结果对象能作为一条赋值语句的左值
// decltype 的结果可以是引用类型
int i42, *p i, r idecltype(r 0) b; //正确加法的结果是int因此b是一个(未初始化的)intdecltype(*p) c; // 错误c是int必须初始化
因为r是一个引用因此decltype(r)的结果是引用类型。
如果想让结果类型是x所指的类型可以把x作为表达式的一部分如r0显然这个表达式的结果将是一个具体值而非一个引用。
另一方面如果表达式的内容是解引用操作则decltype 将得到引用类型。正如我们所熟悉的那样解引用指针可以得到指针所指的对象而且还能给这个对象赋值。因此decltype(*p)的结果类型就是int而非int。 特殊情况
有一种情况需要特别注意对于decltype 所用的表达式来说如果变量名加上了一对括号则得到的类型与不加括号时会有不同。
如果decltype 使用的是一个不加括号的变量则得到的结果就是该变量的类型
如果给变量加上了一层或多层括号编译器就会把它当成是一个表达式。变量是一种可以作为赋值语句左值的特殊表达式所以这样的decltype就会得到引用类型
// decltype的表达式如果是加上了括号的变量结果将是引用
decltype((i)) d; /1 错误d是int必须初始化
decltype(i) e; // 正确e是一个未初始化的int 切记decltype((variable))(注意是双层括号)的结果永远是引用而 decltype(variable)结果只有当 variable 本身就是一个引用时才是引用。 decltype和auto的区别
auto和decltype是C11引入的两个关键字用于类型推导和类型查询。它们的区别如下 auto用于自动推导变量的类型而decltype用于获取表达式的类型。 auto在编译时期根据初始化表达式推导出变量的类型而decltype在编译时期查询表达式的类型不会执行表达式。 auto可以用于初始化变量而decltype不能直接用于变量的初始化。 auto可以推导出值类型、指针类型、引用类型等而decltype更灵活可以推导出表达式的类型包括值类型、指针类型、引用类型、函数类型等。
下面是一些示例来说明它们的区别
int x 10;
auto a x; // 推导出a的类型为int
decltype(x) b x; // 查询x的类型b的类型为intint y x;
auto c y; // 推导出c的类型为int而不是int
decltype(y) d y; // 查询y的类型d的类型为intint foo(int a, int b);
auto result foo(1, 2); // 推导出result的类型为函数返回类型
decltype(foo(1, 2)) e foo(1, 2); // 查询foo(1, 2)的类型e的类型为int 总而言之auto用于方便地推导变量的类型而decltype用于查询表达式的类型。在实际使用中根据需要选择合适的关键字。