[C++] Notes (1)

1.  可以在字符前加 'L' 获得宽字符类型 wchar_t

L'a'

2. 为了与C兼容,C++的字符串文字(literal)也会比输入的字符串多一个字符,每一个字符串文字都以编译器添加的null字符结尾:

 'A' // single quote: character literal
 "A" // double quote: character string literal

"A" 有两个字符: A + NULL

同宽字符文字的表示方法,在字符串前加 L 可以获得宽字符串文字,宽字符串文字也是以宽 NULL 字符结尾:

L"a wide string literal"

3. 可以用空格,tab 或换行连接字符串,例如下面的写法,一行字符串就可以分成多行写:

// concatenated long string literal
std::cout << "a multi-line "
      "string literal "
      "using concatenation"
      << std::endl;
还可以这样写:
string str = "123" "456";
cout << str;  // output 123456

4. 不能连接字符串和宽字符串,下面的行为将是未定义的:

// Concatenating plain and wide character strings is undefined
std::cout << "multi-line " L"literal " << std::endl;

有未定义行为的程序包含错误,如果能work纯属巧合,这类错误编译器不能检测或难于检测。不能依赖于未定义的行为:程序行为可能随编译器或环境发生改变。也不能依赖于具体的平台,例如,不能假定int的size是固定的值,否则,程序将是不可移植的。

5. 可以用 \ 连接多行字符:

// ok: A \ before a newline ignores the line break
      std::cou\
      t << "Hi" << st\
      d::endl;

6. enum 定义,enum 关键字后的名称可选:

// input is 0, output is 1, and append is 2
enum open_modes {input, output, append};
open_modes x = output;

7. 在头文件里应该永远使用完全限定的类名字,不要使用using,原因是使用using会使得这些类名字无条件对其他程序可见,这是不好的。

8. 字符串类型 string, 构造函数:

扫描二维码关注公众号,回复: 583968 查看本文章
string s1;  // Default constructor; s1 is the empty string
string s2(s1);  // Initialize s2 as a copy of s1
string s3("value"); // Initialize s3 as a copy of the string literal
string s4(n, 'c'); // Initialize s4 with n copies of the character 'c'

没有提供参数时,默认构造函数“默认”被调用。

9. 由于历史的原因及为了与C兼容,字符串字面值(string literal)与标准库 string 不是同一个类型。

10. C++ 支持两种形式的变量初始化:copy-initialization, direct-initialization

int ival(1024);     // direct-initialization
int ival = 1024;    // copy-initialization

11. 内建类型变量自动初始化的值:如果在函数体外,值为0,在函数体内则为未初始化。

12. 从终端读入字符串

string s;  // empty string
cin >> s;  // read whitespace-separated string into s
cout << s << endl; // write s to the output

cin >> s 丢弃启始全部空白字符(空格,回车,tab等),直到遇到第二个空白字符,输入 “   hello world”, 将得到输出 “hello”

可以用输入输出操作符将多个读和多个写串在一起,如果输入“hello world”, 则输出“helloworld”

string s1, s2;
cin >> s1 >> s2; // read first input into s1, second into s2
cout << s1 << s2 << endl; // write both strings

13. 读未知数目的字符串

string word;
// read until end-of-file, writing each word to a new line
while (cin >> word)
cout << word << endl;

// output:
// This sentence回车
// This 
// sentence
// while回车
// while
// Ctrl+Z回车     // 如果到达 end-of-file, 就退出while循环
// press any key to continue...
14.  使用 getline 读取整行,
string line;
// read line at time until end-of-file
while (getline(cin, line))
	cout << line << endl;
system("pause");
return 0;
// 不同于cin, getline 不会忽略前导换行符号,遇到换行符号就停止读入并返回, 此newline被丢弃,因此,line 不包括换行符号。

15. string 操作

s.empty()

Returns true if s is empty; otherwise returns false

s.size()

Returns number of characters in s

s[n]

Returns the character at position n in s; positions start at 0.

s1 + s2

Returns a string equal to the concatenation of s1 and s2

s1 = s2

Replaces characters in s1 by a copy of s2

v1 == v2

Returns true if v1 and v2 are equal; false otherwise

!=, <, <=, >, and >=

Have their normal meanings

16. 应该用 string::size_type 存储 size() 返回的结果。size() 的返回类型就是 string::size_type, string 类定义这个类型就是为了实现平台无关性,string::size_type 能容纳足够大的字符串长度。

17.  字符串可以直接赋值:

// st1 is an empty string, st2 is a copy of the literal
string st1, st2 = "The expense of spirit";
st1 = st2; // replace st1 by a copy of st2
赋值较难高效地实现,是因为赋值涉及到一系列操作:删除 st1 已有的存储内容,为存储st2的复制字符分配空间,然后复制。

18. string 和 string 字面值可以相加,但是 + 操作符的至少一个操作数必须是string,不能两个都是 string literal.

string s1("hello");
string s2("world");
string s3 = s1 + ", " + s2 + "\n";
string s1 = "hello";  
string s2 = "world";
string s3 = s1 + ", ";           // ok: adding a string and a literal
string s4 = "hello" + ", ";      // error: no string operand
string s5 = s1 + ", " + "world"; // ok: each + has string operand 
string s6 = "hello" + ", " + s2; // error: can't add string literals

s5 的赋值是ok的,因为 + 操作符号结合顺序从左到右,(s1 + ",") 返回string对象,可以再次与 literal "world"相加

string s5 = (s1 + ", ") + "world";

s6 的赋值错误,有以下改法:

string s6 = "hello" ", " + s2;
string s6 = "hello" + (", " + s2);
string s6 = string("hello") + ", " + s2;

之所以不能用 + 连接两个字符串字面值, 是因为,字符串字面值是字符数组(一个const char [N]N 为字符串长度加 1 (null 终止符)), 绝大多数情况下,数组被转换为指向起始元素的指针。所以表达式"Hello" + ",world"是试图将两个const char*相加,指针相加是无意义的。              

19. 运算符左右两边式子的 计算顺序, C++只对一下四个操作符号有规定,其他是没有规定的,编译器可以先计算左边的,也可以先计算右边的。

(1)  &&   (2)  ||         (3) ? :       (4)  ,

20. 用下标subscript操作符[]取字符串中的元素,index的类型应该是 string::size_type,index不能超过s.size() - 1,

string str("some string");
for (string::size_type ix = 0; ix != str.size(); ++ix)
    cout << str[ix] << endl;

21. 对于字符串中的单个字符的一系列函数:

isalnum(c)

true if c is a letter or a digit.

isalpha(c)

true if c is a letter.

iscntrl(c)

true if c is a control character.

isdigit(c)

true if c is a digit.

isgraph(c)

true if c is not a space but is printable.

islower(c)

true if c is a lowercase letter.

isprint(c)

true if c is a printable character.

ispunct(c)

true if c is a punctuation character.

isspace(c)

true if c is whitespace: space, tab, vertical tab, return, newline, formfeed

isupper(c)

TRue if c is an uppercase letter.

isxdigit(c)

true if c is a hexadecimal digit.

tolower(c)

If c is an uppercase letter, returns its lowercase equivalent; otherwise returns c unchanged.

toupper(c)

If c is a lowercase letter, returns its uppercase equivalent; otherwise returns c unchanged.

头文件: <cctype>, (但是我发现没有这个头文件,也可以build pass)

返回string中标点符号数:

string s("Hello World!!!");
string::size_type punct_cnt = 0;
// count number of punctuation characters in s
for (string::size_type index = 0; index != s.size(); ++index)
    if (ispunct(s[index]))
        ++punct_cnt;
cout << punct_cnt
    << " punctuation characters in " << s << endl;

Concatenate two string literals

C++ Primer

猜你喜欢

转载自blog.csdn.net/ftell/article/details/80014370