What & How & Why

差别

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

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
cs:programming:cpp:courses:cpp_basic_deep:chpt_1 [2024/04/13 13:32] – [Iostream] codingharecs:programming:cpp:courses:cpp_basic_deep:chpt_1 [2024/04/14 12:53] (当前版本) – [结构体 / 自定义类型] codinghare
行 72: 行 72:
   * 输出流:''cout'' / ''cerr'' / ''clog''   * 输出流:''cout'' / ''cerr'' / ''clog''
     * ''cerr'' 可以定向到不同的文件中,作为错误的输出     * ''cerr'' 可以定向到不同的文件中,作为错误的输出
-<code bash>main > txt1 2>txt2<code>+<code bash> 
 +#cout 的内容会输出到 OutputText 
 +#cerr 的内容会输出到 ErrorText 
 +./main > OutputText 2>ErrorText 
 +</code> 
 +  * ''clog'' 与 ''cerr'' 的区别在于是否立即刷新**缓冲区**: 
 +    * ''cerr'' 输出的是错误信息,因此需要立即刷新缓冲区 
 +    * ''clog'' 输出的是日志信息,因此不会立即刷新缓冲区 
 +  * 手动刷新:''std::flush'' / ''std::endl'',但大量刷新存在性能问题,因此推荐只在必要的时候使用。 
 + 
 +<WRAP center round box 100%> 
 +缓冲区是内存中的一个区域,用于优化读写的速度。缓冲区满了以后,会一次性将内容输出。但问题在于,程序没有正常结束时,缓冲区中的内容会丢失。如果为了查找程序的 Bug,那么这部分内容是需要保留的。这种情况下,需要立即刷新缓冲区。 
 +</WRAP> 
 +===命名空间=== 
 +命名空间的存在是为了防止命名冲突。多人开发的过程中很可能会存在同名函数,放在一起可能会存在调用的冲突。这种情况下可以选择将其分置于不同的命名空间内: 
 +<code cpp> 
 +namespace NS1 { 
 +    void fun() { 
 +        std::cout << "NS1" << std::endl; 
 +    } 
 +
 + 
 +namespace NS2 { 
 +    void fun() { 
 +        std::cout << "NS2" << std::endl; 
 +    } 
 + 
 +
 +</code> 
 +没有标明命名空间的函数属于**全局空间**(//global space//): 
 +<code cpp> 
 +void fun() 
 +
 +    std::cout << "global fun"; 
 +
 +</code> 
 +调用的方式有三种: 
 +  * ''::'' 域解析符调用: 
 +<code cpp> 
 +// call 
 +int main(int argc, char const *argv[]) 
 +
 +    NS1::fun(); 
 +    NS2::fun(); 
 +
 +</code> 
 +  * ''using'' 调用 
 +<code cpp> 
 +using namespace NS1; 
 +fun(); 
 +</code> 
 +<code bash> 
 +# output 
 +# 如果 NS1 中定义了 fun() 
 +NS1 
 +# 如果 NS1 中没有定义 fun(), 全局中定义了 fun() 
 +global fun 
 +</code> 
 +<WRAP center round box 100%> 
 +  * 如果都定义了 ''fun()'',课程中说会先调用全局 ''fun()'',但测试发现 gcc 13.1.0 报错二义性。慎用 
 +  * ''using'' 会导致整个命名空间暴露给其他使用者,应当尽量使用域解析符。 
 +</WRAP> 
 +  * 名字空间别名:使用别名代替完整的命名空间名进行调用: 
 +<code cpp> 
 +namespace n = NS1; 
 +n::fun(); 
 +</code> 
 +==std 命名空间== 
 +  * std 命名空间是 C++ 标准库的命名空间,用法与上述的命名空间用法相同。 
 +  * name mangling:C++ 会为不同命名空间下的相同 name 进行变化,为链接使用: 
 +<code bash> 
 +# checking the mangling data 
 +nm main.o - o 
 +# demangling,查看 mangling 之前的原始数据 
 +nm main.o - o | c++filt -t 
 +</code> 
 +<WRAP center round box 100%> 
 +''main()'' 不会做 mangling,因为 ''main()'' 是唯一的。 
 +</WRAP> 
 +====控制流==== 
 +  * if statement:通过选择分支来选择执行的代码 
 +    * 条件部分:判断是否执行 
 +      * 使用**相等**(''=='')而不是**赋值** ''='' 
 +      * 赋值表达式会被解释为 (y = 42 -> 42),而 42 会被转化为布尔值 ''true'',因此赋值表达式恒为真。 
 +      * 使用 ''const'' 阻止赋值表达式作为调价 
 +    * 语句部分:要执行的操作 
 +  * while statement:循环条件判断 
 +====结构体 / 自定义类型==== 
 +  * 结构体:可以将不同的数据放置在一起,并使用 ''.'' 操作符访问内部元素 
 +  * 结构体可以作为参数被传入函数 
 +  * 结构体可以设置自己的成员函数 
 +<code cpp> 
 +struct Point 
 +
 +    int x = 1; 
 +    int y = 2; 
 +    //member function 
 +    Point fun(Point p) 
 +    { 
 +        p.x += 1; 
 +        p.y += 1; 
 +        return p; 
 +    } 
 +}; 
 + 
 +int main(int argc, char const *argv[]) 
 +
 +    Point p; 
 +    //call 
 +    p = p.fun(p); 
 +    std::cout << p.x << " " << p.y << std::endl; 
 +
 +</code>