What & How & Why

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
cs:programming:cpp:courses:cpp_basic_deep:chpt_2 [2024/04/16 13:52] – [decltype] codingharecs:programming:cpp:courses:cpp_basic_deep:chpt_2 [2024/08/11 03:50] (当前版本) – [常量表达式指针] codinghare
行 125: 行 125:
 int main() int main()
 { {
-    std::cout << g_x << std::endl;+    std::cout << << std::endl;
 } }
 </code> </code>
行 242: 行 242:
 ==指针的引用== ==指针的引用==
   * 指针是对象,因此存在指针的引用:   * 指针是对象,因此存在指针的引用:
-  * 引用不是对象,因此不存在引用的+  * 引用不是对象,因此不存在引用的
 <code cpp> <code cpp>
 int* &refPx = ptr; int* &refPx = ptr;
行 305: 行 305:
 // y1 是在运行期确定的(运行期常量) // y1 是在运行期确定的(运行期常量)
 const int y1 = y; const int y1 = y;
-// y2 是在编译期确定的(编译常量)+// y2 是在编译期确定的(编译常量)
 const int y2 = 3; const int y2 = 3;
 </code> </code>
行 311: 行 311:
   * ''y1'' 会以“期待运行期有输入的”方式进行汇编   * ''y1'' 会以“期待运行期有输入的”方式进行汇编
   * ''y2'' 对编译器可见,那么 ''y2 == 3'' 一定为真。因此,编译器不会进行 ''if'' 的判断,而会直接执行该 if 下的代码段。(优化)   * ''y2'' 对编译器可见,那么 ''y2 == 3'' 一定为真。因此,编译器不会进行 ''if'' 的判断,而会直接执行该 if 下的代码段。(优化)
-也就是说,编译器常量是可以被编译器优化的。这也是常量表达式的由来:C++ 11 中通过 ''constexpr'' 关键字,将常量直接声明为**编译期量**。也就是说,上述的 ''const int y2 = 3'' 可以写为:+也就是说,编译器常量是可以被编译器优化的。这也是常量表达式的由来:C++ 11 中通过 ''constexpr'' 关键字,将常量直接声明为**编译期量**。也就是说,上述的 ''const int y2 = 3'' 可以写为:
 <code cpp> <code cpp>
 // y2 被显式的声明为编译期常量 // y2 被显式的声明为编译期常量
行 319: 行 319:
 </code> </code>
 ==常量表达式指针== ==常量表达式指针==
-指针也可以作为编译常量。这种情况下,需要满足两个条件:+指针也可以作为编译常量。这种情况下,需要满足两个条件:
   * 指针是常量   * 指针是常量
   * 指针指向的内容也是常量   * 指针指向的内容也是常量
-只有满足这两个条件,指针才能作为编译常量对编译器可见。也就是说,这种情况下的指针类型是 ''const type* const''+只有满足这两个条件,指针才能作为编译常量对编译器可见。也就是说,这种情况下的指针类型是 ''const type* const''
 <code cpp> <code cpp>
 constexpr const int* ptr = nullptr; constexpr const int* ptr = nullptr;
行 399: 行 399:
 </code> </code>
 ==decltype== ==decltype==
-  * ''decltype(exp(r-value))'' 需要一个表达式,并返回表达式的类型。decltype 与 auto 的区别在于,decltype **不会产生类型退化**。+decltype 获取一个表达式,并返回表达式的类型。decltype 与 auto 的区别在于,decltype **不会产生类型退化**。 
 +  
 +   * decltype(val):''val'' 代表 entity(**变量名称**),那么 ''val'' 是什么类型,那么返回的就是什么类型
 <code cpp> <code cpp>
 +//x is an variable name
 int x = 3; int x = 3;
-int& y1 = x; 
 //int //int
-auto y2 = y1;+decltype(x); 
 +//注意加括号的形式,(x) 是表达式, x 是变量名
 //int& //int&
-decltype(y1y3 = y1;+decltype((x));
 </code> </code>
- * decltype(val)''val''表 entity(**变量名称**)那么 ''val'' 是什么类型,那么返回的什么类型+  ''decltype(exp(r-value))'' :如果达式是非变量名称的表达式且为右值,那么返回的是表达式评估后的类型
 <code cpp> <code cpp>
-//x is an variable name 
 int x = 3; int x = 3;
 +int& y1 = x;
 //int //int
-decltype(x); +auto y2 = y1;
-//注意加括号的形式,(x) 是表达式, x 是变量名+
 //int& //int&
-decltype((x));+decltype(y1y3 = y1;
 </code> </code>
   * ''decltype(exp(l-vaule))'':如果表达式为非变量名称的左值(通常带运算符),返回的类型会自动加上一个**引用**   * ''decltype(exp(l-vaule))'':如果表达式为非变量名称的左值(通常带运算符),返回的类型会自动加上一个**引用**
行 425: 行 427:
 decltype(*ptr); decltype(*ptr);
 </code> </code>
-  +  * decltype(auto) [C++14]:用于简化 decltype 的使用 
-  * decltype(auto) [C++14]+<code cpp> 
 +//非常繁琐的写法 
 +decltype(3.5+15l) x  = 3.5 + 15l; 
 +//C++ 14 的写法 
 +// 用 auto 来代表繁琐的表达式,并不会导致退化 
 +// 编译器会将 auto 替换为赋值运算符右边的内容 
 +decltype(autol) x  = 3.5 + 15l; 
 +</code> 
 +  * concept auto [C++20]:任何 concept 都会包含一系列类型,这些类型的共同特征都可以用 concept 表示。比如 ''int'', ''long'' 都可以表示为 ''std::intergal'' 
 +    * concept auto 让自动推导受 concept 的范围限制,比如让 auto 只能推断出整数类型的类型: 
 +<code cpp> 
 +#include <concepts> 
 +int main() 
 +
 +    //int 
 +    std::integral auto z = 3; 
 +    //error, 3.5 is not an integral 
 +    std::integral auto z = 3.5; 
 +
 +</code> 
 +====域和对象生命周期==== 
 +===域 Scope=== 
 +域代表了程序的一部分,域中的 name 有**唯一的含义**: 
 +  * 全局域:程序最外部的域,全局对象 
 +  * 块域:大括号限定的域,局部对象 
 +  * 其他类型的域:Namespace, class 等等 
 +域可以进行嵌套,内部域中的 Name 会掩盖外部域中的 Name: 
 +<code cpp> 
 +int x = 3; 
 +int main() 
 +
 +   int x = 4; 
 +   //call local x 
 +   std::cout << x << '\n'; 
 +
 +</code> 
 +===对象生命周期=== 
 +生命周期指对象从被**初始化到被销毁**的区间。 
 +  * 全局对象:生命周期为程序的运行期 
 +  * 局部对象:起始于**初始化**,结束于域的执行完成