C++ 基础知识:
-
C++运行和调试:C++编码完毕的程序的运行简单来说经历编译和运行两个步骤,在各个操作系统中有所不同。
- Windows系统中,一般带有编译C++的IDE,编译完毕后,切换到.exe文件所在路径,直接输入被编译的软件名,如下命令运行放在C:\exmaples\ch01 这个文件夹中名为GuessNumber的应用
cd C:\\exmaples\\ch01 GuessNumber
备注:如果文件在其他盘,则要切换盘名,例如
d:
表示切换到d盘。
- Linux系统中,切换到.cpp文件所在路径后依次输入以下命令:
```
g++ GuessNumber.cpp -o GuessNumber
./GuessNumber
```
(C++11 chap1)
- C++运算对于操作符是有优先级顺序的,详情参考参考资料中的链接。(C++11 chap2)
- 一般情况下,C++中用户自定义的类类名应当遵循首字母大写的原则(Pascal case)。广义来说,C++的类名允许首字母大写或小写(Camel case)。(C++11 chap3.2 p.g.39)
- 类的方法中若带有const关键字,表示此方法不得修改类所对应的对象属性。例如:```
void display() const
```。(C++11 chap 3.2 p.g.40)更多关于const变量的信息,可以参考博文:https://my.oschina.net/SamYjy/blog/823131
- getline(in_stream, str)表示从输入媒介中读取一行字符串赋值给str变量。(C++11 chap 3.3 p.g.42)
- explicit:若类构建(又名构造函数或constructor)的传入参数仅为一个时,如果代码不希望编译时可能的隐式转化发生,则需要在类构建名前面加上关键字explicit。(C++11 chap 3.5 p.g.52,C++11 chap 10.13 p.g.338 - 340)
- C++头文件中(.h文件),尽量不要出现using语句。#include语句用<>表示导入C++的STL头文件,用""表示导入用户自定义的头文件。(C++11 chap 3.6 p.g.56 - 57)
- static_cast<double>(total):表示将非double类型变量total暂存为double变量,常用在C++的浮点运算中作为C++11推荐的强制转换方式。(C++11 chap 4.7 p.g.90)
- STL头文件<iomanip>包含有流操作函数如setprecision以及流操作常量如fixed以及showpoint(C++11 chap 4.7 p.g.90),left,setw等。其中有的操作符具有粘滞性,有的则没有。(C++11 chap 5.4 p.g.110)其中如用于显示true或false的boolalpha即为粘性操作符(C++11 chap 5.8 p.g.125)
- STL头文件<climits>含有表示系统极限值的常量相关信息,如UINT_MAX表示系统最大无符号整数。(C++11 chap 4.7 p.g.91)。
- C++11有一种初始化方式为列表初始化,例如假设Employee类的构造函数定义为
Employee(string first, string family, double salary);
则该类的初始化可以为:
Employee em1{“Bob”, “Blue”, 1234.56};
(C++11 chap 4.8 p.g.94)。
- 关于include关键字的使用:\#include加双引号表示导入用户自定义的文件,用\#include加尖括号表示导入系统路径的可编译文件。(C++11 chap 3.6 p.g.57)其中,头文件一般不会出现using语句,using语句一遍出现在.cpp文件中。(C++11 chap 3.6 p.g.56)
- cin.get()用于获得下一个字符,用法例如:
int grade = cin.get(); //其中grade是一个可以容纳字符串的变量
EOF为结束符,在头文件<stdio.h>中,可以通过在Linux系统中输入<ctrl>d或Window系统中输入<ctrl>z实现。(C++11 chap 5.6 p.g.116)
- C++的初始化允许向构造函数传入多个参数,例如如下用法:
GradeBook::GradeBook(string name): aCount(0), bCount(0)...
(C++11 chap 5.6 p.g.113)
- 在循环读取中若要获取忽略换行、制表符和空格的字符,示例代码如下:
switch(character): ... case '\n': case '\t': case ' ': break;
(C++11 chap 5.6 p.g.115)
### C++11函数、模版和向量基本知识
- C++的函数分为全局函数和成员函数,不是在类内的函数称为全局函数,例如main函数,<cmath>头文件中的函数等。(C++11 chap 6.2 p.g.130)
- 若做出对于sqrt函数传入一个负数等类似情形的,头文件<cerrno>中的常量errno会被设置为EDOM常量。(C++11 chap 6.2 p.g.131)
- 函数头(function prototype):定义函数名、返回值类型以及接收参数的函数标题。(C++11 chap 6.4 p.g.137)
- C++11标准头文件为中含有实现C++各类功能的库函数。比如<iostream>和<iomanip>与I/O操作有关,<typeinfo>与运行时的种类有关。(C++11 chap 6.5 p.g.139 - 141)
- C++中的枚举使用方式见以下例子:
//enumeration with constants that represent the game status enum Status { CONTINUE, WON, LOST }; // all caps in constants Status gameStatus = CONTINUE; // can contain CONTINUE, WON or LOST //Omit unimportant parts. switch (sumOfDice) { case 7: // win with 7 on first roll case 11: // win with 11 on first roll
gameStatus = WON; break; case 2: // lose with 2 on first roll case 3: // lose with 3 on first roll case 12: // lose with 12 on first roll
gameStatus = LOST; break; default: // did not win or lose, so remember point gameStatus = CONTINUE; // game is not over break; // optional at end of switch } // end switch // while game is not complete while (CONTINUE == gameStatus) // not WON or LOST { //Do sth. } // end while
// display won or lost message
if (WON == gameStatus)
//DO SOMETHING
//And so on..
枚举还能写成枚举类,这样能防止枚举参数重名。枚举类的书写和方式例如:
enum class Status { CONTINUE, WON, LOST }; //获取类中成员使用单元界定符(::) Status gameStatus = Status::CONTINUE;
C++11还允许声明任何整形变量的枚举(比如枚举变量可以是字符型、长整型等)
enum class XX : unsigned I{} (p.g.150), where I could be any integral type.
(C++11 chap 6.7 p.g.149 - 150)
- C++11推荐的随机数使用方式:
E.G. In the definition: #include<random> //in the function that needs random number: default_random_engine engine( static_cast<unsigned int>( time(0) ) ); uniform_int_distribution<unsigned int> randomInt(1, 6); int num = randomInt(engine);
- static表示暂存的意思,被static关键词修饰的变量在其作用域内被暂存,程序未结束前再次调用作用域时保持上次结果不变。(C++11 chap 6.10 p.g.155 - 156)
- inline函数被编译时,凡是调用此函数的代码都会产生一份函数的整体备份,从而使常用函数调用被加速。但是此关键词造成代码长度过长。(C++11 chap 6.10 p.g.163 - 164)
- 关于引用的一些知识:引用(reference)比较适合与不同方法间传递字节空间较大的参数,不过它可能导致被传递参数在被调用的方法中被意外修改的情形。此外,方法的返回值不宜为引用,否则容易导致悬挂引用(dangling references),当变量使用悬挂引用时可能导致逻辑错误。(当对象使用层叠调用时本条例外)(C++11 chap 6.14 p.g.165 - 167)此外,使用引用可以使得增强型循环中的变量被修改,示例程序如下:
for(int &itemRef : items) itemRef *= 2;
- C++数组中,如果一个多为数组被定义为const,则其每个子数组都应被定义为const。
- 从一个向量初始化另一个向量的用法示例:
vector<int> integers3( integers1 );
C++单元界定符(::)不仅可以用来调用类或枚举内部的变量(如前述枚举中提到的情况),还可以在类的内部调用全局变量。如以下程序:
int num = 7;
int main(int argc, char** argv) { double num = 0.5;
cout << "Local num: " << num << "\n" #输出为局部变量0.5
<< "Global num: " << ::num << endl; #输出为全局变量7
return 0;
}
### C++11指针使用手记
- 什么是指针(定义):含有某个有值变量内存地址的变量叫做指针。从这个定义来说,指针变量存储的是一个内存地址,该地址对应一个变量,变量含有一个值。从该指针寻址到地址从而获得变量值的过程叫做去指针化(dereferencing或indirection)。(C++11 Chap 8.1 p.g.229)
- 指针必须被初始化为nullptr变量,这样做可以防止指针指向内存中的不明区域。(C++11 Chap 8.2 p.g.229)
- 指针变量的定义:被定义为指针的变量被前置操作符星号(*),因此,如果星号出现在定义中,表示的意思是是定义了一个指针变量。此外,一般定义指针变量时可在变量名后加上Ptr三个字符,表示指向相应变量的指针。例如:
int count, * countPtr; double *xPtr, *yPtr
备注:指针的定义中每个指针变量前面都要加上星号。否则会被误认为普通变量定义。(C++11 Chap 8.2 p.g.230)
- C/C++内置数组的几个特点:
- 相互之间不可比较
- 相互之间不能直接赋值
- 无法知道自身元素数量
- 不提供越界检查(C++11 Chap 8.5 p.g.240)
- 关于指针变量和const关键字之间的关系,详见博文:https://my.oschina.net/SamYjy/blog/822461 《浅谈C++指针变量与const关键字》
- sizeof 关键字的几点说明:
- 当sizeof作为关键字后面直接加上内置数组名时,返回值为该内置数组所含有的字节总量。
- 当sizeof作为函数被传入一个内置数组名时,返回值为本系统指针的长度(一般为4字节)
- 使用sizeof作为关键字除以sizeof加上数组类型,则可以得出内置数组的元素个数
- 当类型名作为参数与sizeof搭配使用时,sizeof必须只能作为函数。其它情况则没有关系。
示例程序:
#include <cstdlib> #include <iostream> using namespace std;
size_t getSize(double []);
int main(int argc, char** argv) { double nums[20]; cout << "Number of bytes in the array is: " << sizeof nums << endl; cout << "Number of bytes returned by getSize is " << getSize(nums) << endl; return 0; }
//Write this as size_t getSize(double * ptr) has the exact same effect. size_t getSize(double ptr[]){ return sizeof ptr; }
![输入图片说明](https://static.oschina.net/uploads/img/201706/01180246_E4aR.png "在这里输入图片标题")
(C++11 Chap 8.7 p.g.244-247)
- 指针赋值若干规则:
- 若两个指针变量种类相同,则它们之间可以直接相互赋值。
- 任何种类的指针都可以被赋值给void指针,但是void指针赋值给其他指针时需要类型转换。
- 禁止将void指针去指针化,理由是编译器无法获知void指针所对应的每个变量的大小。
(C++11 Chap 8.8 p.g.249)
### C++11 C型字符串使用手记
- 字符变量:是指放在单引号中的字符,通常可以转化为整型变量。
- C型字符串:C型字符串是指类型为字符变量并且以终止符号结尾('\0')的内置数组。不带终止符号的C型字符串可能会覆盖内存中原有的内容,并导致逻辑错误以及潜在的计算机安全方面的问题。
- 对C型字符串作sizeof操作,得到的数值是**包含了终止符号的字符串长度**。
(C++11 Chap 8.10 p.g.252 - 255)
示例代码:
const char color[] = "blue"; //Or same as const char color[] = {‘b’, ‘l’, ‘u’, ‘e’, ‘\0’}; const char * colorPtr = "blue";
cout << "Size of color: " << sizeof color << endl; //Contains the measure of ‘\0’ cout << "Size of colorPtr: " << sizeof colorPtr << endl; //measure the size of ptr.
![输入图片说明](https://static.oschina.net/uploads/img/201706/01182759_fdYo.png "在这里输入图片标题")
- 字符串在程序中为静态存储,因此同一个字符串有可能同时被多个程序调用。基于这一点,建议修改字符串内容之前先将其备份。(存入另一个字符串指针)
- 使用setw函数可以限定字符串的最大长度。例如,
cin >> setw(20) > word;
就限定了word的最大长度为19个字符,最后的第20位为终止符号。setw是一个非粘性操作符。如果用户输入超过了19个字符,剩余字符仍然会被保存在输入流中,并且可能被下一个输入流使用。(C++11 Chap 8.10 p.g.252 - 255)
- C++预编译操作使用示例详见:https://my.oschina.net/SamYjy/blog/827660
参考资料:
1. C++操作符优先级,URL:http://baike.baidu.com/link?url=GMp7NmzrdcJSpphb-6lHdrs_dXDyXEqHoNMrq0HyyG0Sm6K7rRviSOrRgSZtzkhWfjo4Y2VQoBifmlRhqK2R9q58GxTwIiwTSC-9be3kNomZCRCXx6VSZC5Gnq9igS7Oq_pOwK_OpR3AVawOnbBxLq#3
1. Paul Deitel & Harvey Deitel, C++11程序设计(英文版)(第2版),本文中C++11括号所表示的资料