ITPub博客

首页 > 应用开发 > Java > 《C++ Primer第五版》读书笔记(3)

《C++ Primer第五版》读书笔记(3)

原创 Java 作者:davidwang9527 时间:2014-02-09 20:44:35 0 删除 编辑


1      Strings, Vectors, and Arrays


1.1     Namespace using Declarations


Headers Should Not Include using Declarations: The reason is that the contents of a header are copied into the including program’s text. If a header has a using declaration, then every program that includes that header gets that same using declaration. As a result, a program that didn’t intend to use the specified library name might encounter unexpected name conflicts.



1.2     Library string Type


1.2.1        Defining and Initializing strings:


1.string s1;  // default initialization; s1 is the empty string
2.string s2 = s1;  // s2 is a copy of  s1,
copy initialization
string s2( s1);  // s2 is a copy of  s1, direct initialization
3.string s3 = "hiya";  // s3 is a copy of the string literal,
copy initialization
string s3 ("hiya");  // s3 is a copy of the string literal, direct initialization
4.string s4(10, 'c');  // s4 is cccccccccc,
direct initialization



1.2.2        Operations on strings:


clip_image002



When we mix strings and string or character literals, at least one operand to each +operator must be of string type:



string s1 = "hello", s2 = "world";
string s6 = s1 + ", " + "world"; // ok: each + has a string operand(
要从左往右看,第二个加号时前面是string)
string s7 = "hello" + ", " + s2; // error: can't add string literals(
要从左往右看,第一个加号两边都是literal,没有string type).



The string::size_type Type



Although we don’t know the precise type of string::size_type, we do know that it is an unsigned type big enough to hold the size of any string.



It can be tedious to type string::size_type. Under the new standard, we can ask the compiler to provide the appropriate type by using auto or decltype



string::size_type len1=line.size();
auto len2=line.size();
decltype(line.size()) len3=line.size();



Because size returns an unsigned type, it is essential to remember that expressions that mix signed and unsigned data can have surprising results . For example, if n is an int that holds a negative value, then s.size() < n will almost surely evaluate as true. It yields true because the negative value in n will convert to a large unsigned value.



1.2.3        Dealing with the Characters in a string


These functions are defined in the cctype header.



clip_image004



Advice:Use the C++ Versions of C Library Headers



Inaddition to facilities defined specifically for C++, the C++ library incorporates the C library. Headers in C have names of the form name .h.The C++ versions of these headers are named c name—they remove the .h suffix and precede the name with the letter c. The c indicates that the header is part of the C library.



Hence, cctype has the same contents as ctype.h, but in a form that is appropriate for C++ programs. In particular, the names defined in the cname headers are defined inside the std namespace, whereas those defined in the .h versions are not.



Ordinarily,C++ programs should use the c name versions of headers and not the name .h versions. That way names from the standard library are consistently found in the std namespace. Using the .h headers puts the burden on the programmer to remember which library names are inherited from C and which are unique to C++.



Range For(大赞,此功能让我想起了PLSQLCursor FOR游标,简单易用,不用担心下标越界导致的buffer overflow了)



If we want to do something to every character in a string, by far the best approach is to use a statement introduced by the new standard: the range for statement.



for(declaration: expression)



statement



例子一:



string str("some string");
// print the characters in str one character to a line
for (auto c : str)  // for every char in str
    cout << c << endl;  // print the current character followed by a newline



 


例子二:



string s("Hello World!!!");
// punct_cnt has the same type that s.size returns; see § 2.5.3 (p. 70)
decltype(s.size()) punct_cnt = 0;
// count the number of punctuation characters in s
for (auto c : s)  // for every char in s
   if (ispunct(c))  // if the character is punctuation
     ++punct_cnt;  // increment the punctuation counter



cout << punct_cnt<< " punctuation characters in " << s << endl;



 


例子三(Using a Range for to Change the Characters in a string)



strings("Hello World!!!");
// convert s to uppercase
for (auto &c : s)  // for every char in s (note: c is a reference)
    c = toupper(c); // c is a reference, so the assignment changes the char in s
cout << s << endl;



 


当然如果要遍历string的所有字符,或者是要随机访问,还是要使用subscript(下标)来访问string



1.3     Library vector Type


A vector is a collection of objects, all of which have the same type. Every object in the collection has an associated index, which gives access to that object. A vector is often referred to as a container because it “contains” other objects.



vector is a template, not a type. Types generated from vector must include the element type.



It is worth noting that earlier versions of C++ used a slightly different syntax to define a vector whose elements are themselves vectors (or another template type). In the past, we had to supply a space between the closing angle bracket of the outer vector and its element type—vector >rather than vector>.



1.3.1        Defining and Initializing vectors


clip_image006



其中v4会初始化n个空的element.



vectorv1(10);  // v1 has ten elements with value 0
vector v2{10};  // v2 has one element with value 10
vector v3(10, 1); // v3 has ten elements with value 1
vector v4{10, 1}; // v4 has two elements with values 10 and 1



When we use parentheses, we are saying that the values we supply are to be used to
construct the object.
When we use curly braces, {...}, we’re saying that, if possible, we want to list initialize the object.



Onthe other hand, if we use braces and there is no way to use the initializers to list initialize the object, then those values will be used to construct the object(何必搞这种绕人的功能呢?真应该直接报错!)



vector v5{"hi"}; // list initialization: v5 has one element
vector v6("hi"); // error: can't construct a vector from a string literal
vector v7{10};  // v7 has ten default-initialized elements
vector v8{10, "hi"}; // v8 has ten elements with value "hi"



1.3.2        Adding Elements to a vector(好帅的功能!)


use a vector member named push_back to add elements at run time.



The standard requires that vector implementations can efficiently add elements at run time. Because vectors grow efficiently, it is often unnecessary—and can result in poorer performance—to define a vector of a specific size. The exception to this rule is if all the elements actually need the same value.



Starting with an empty vector and adding elements at run time is distinctly different from how we use built-in arrays in C and in most other languages. In particular, if you are accustomed to using C or Java, you might expect that it would be best to define the vector at its expected size. In fact, the contrary is usually the case



1.3.3        Other vector Operations


clip_image008



We access the elements of a vector the same way that we access the characters in a string:through their position in the vector. For example, we can use a range for to process all the elements in a vector.



1.4     Introducing Iterators


Although we can use subscripts to access the characters of a string or the elements in a vector, there is a more general mechanism—known as iterators—that we can use for the same purpose.



// the compiler determines the type of b and e; see § 2.5.2 (p. 68)
// b denotes the first element and e denotes one past the last element in v
auto b = v.begin(), e = v.end(); // b and e have the same type(
又见auto,这功能真好!)



The iterator returned by end is an iterator positioned “one past the end” of the associated container (or string). This iterator denotes a nonexistent element “off the end” of the container. It is used as a marker indicating when we have processed all the elements. The iterator returned by end is often referred to as the off-the-end iterator or abbreviated as “the end iterator.”



clip_image010



for (auto it = s.begin(); it != s.end() && !isspace(*it);++it)



*it = toupper(*it); // capitalize the current character



the library types that have iterators define types named iterator and const_iterator that represent actual iterator types:



vector::iterator it; // it can read and write vector elements
string::iterator it2;  // it2 can read and write characters in a string
vector::const_iterator  it3; // it3 can read but not write elements
string::const_iterator it4;    // it4  can read but not write characters



A const_iterator behaves like a const pointer. Like a const pointer, a const_iterator may read but not write the element it denotes; an object of type iterator can both read and write. If a vector or string is const, we may use only its const_iterator type. With a nonconst vector or string, we can use either iterator or const_iterator.

To let us ask specifically for the const_iterator type, the new standard introduced two new functions named cbegin and cend:
auto it3 = v.cbegin(); // it3 has type vector::const_iterator



1.5     Arrays


An array is a data structure that is similar to the library vector type but offers a different trade-off between performance and flexibility. Like a vector, an array is a container of unnamed objects of a single type that we access by position. Unlike a vector, arrays have fixed size; we cannot add elements to an array. Because arrays have fixed size, they sometimes offer better run-time performance for specialized applications. However, that run-time advantage comes at the cost of lost flexibility.



1.5.1        Defining and Initializing Built-in Arrays


An array declarator has the form a[d]. The number of elements in an array is part of the array’s type. As a result, the dimension must be known at compile time, which means that the dimension must be a constant expression



unsignedcnt = 42;  // not a constant expression
constexpr unsigned sz = 42; // constant expression
// constexpr see § 2.4.4 (p. 66)
int arr[10];  // array of ten ints
int *parr[sz];  // array of 42 pointers to int
string bad[cnt];  // error: cnt is not a constant expression
string strs[get_size()]; // ok if get_size is constexpr, error otherwise



 


Although we can compute an off-the-end pointer, doing so is error-prone. To make it easier and safer to use pointers, the new library includes two functions, named begin and end.



int ia[] = {0,1,2,3,4,5,6,7,8,9}; // ia is an array of ten ints
int *beg = begin(ia); // pointer to the first element in ia
int *last = end(ia);  // pointer one past the last element in ia



Modern C++ programs should use vectors and iterators instead of built-in arrays and pointers, and use strings rather than C-style array-based character strings.



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29464142/viewspace-1078555/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2014-01-28

  • 博文量
    3
  • 访问量
    21559