C++自修入門實境秀、C++ Primer 5版研讀秀 20/ ~頁127 Subscripting a Multidimensional Ar...





2:30

3.5.4. C-Style Character Strings C式的字元字串

→一種C風格的字串處理方式

C-style strings are not a type. Instead, they are a convention for how to represent and use character strings. 3:1:00

convention就是Style的由來,有怎樣的習慣和風格,自然就有怎樣的stype(型)了。

C Library String Functions

12:05

22:00一定要是最後一個元素為null(null terminated)的陣列,其指標(調用陣列時其實是調用其第一元素的指標)才能代入至表3.8的函式作引數



表3.8

strcmp(p1, p2) 39:00

Comparing Strings

31:20

string有兩種:

1.程式庫型別的string(library string)

2.C-Style string(西式字串、西型字串)



頁123

34:30

37:20指標的比較一定是指向(定址)相同的物件,才有意義

Caller Is Responsible for Size of a Destination String

1:1:30 呼叫者負責目的字串的大小

這都太不夠中文化的翻譯→

最後的結果必須是容得下字串運算結果的變數

1:6:00

The array we pass must be large enough to hold the generated string, including the null character at the end.

42:40

目的字串的大小是多少是由呼叫者來負責的

46:00

將兩個指標相加是無效(不對的illegal)且沒有意義的。

Instead we can use strcat and strcpy.

51:00

instead可以翻成中文的「那」

(非要這麼做不可的話)那我們可以



55:30

The code we show here, although a common usage pattern, is fraught with potential for serious error:

雖然我們這裡顯示的程式是常見的模式,但這樣的程式用起來依然是讓人步步驚心←

我們在此展示的程式碼,雖然是一種常見的使用模式,但滿載了導致嚴重錯誤的可能性:

仍是處處都是(佈滿了)陷阱

仍是處處是地雷

1:9:55

1:28:00 自訂取得陣列大小的兩種函式:

size_t sizeofanArrayEnd_Beg() {//用程式庫的 begin 和 end來算陣列的size

int arr[]{ 0,11,2,3,4,15 };

return end(arr) - begin(arr);

}

size_t sizeofanArray_sizeof() { //用 sizeof來計算

int arr[]{ 0,11,2,3,4,15 };

return sizeof(arr) / sizeof(*arr);

}

1:33:00

Unfortunately,programs similar to this code are widely distributed. Programs with such code are error-prone and often lead to serious security leaks.

遺憾的是,類似這裡程式碼的程式廣為散布。帶有這種程式碼的程式很容易出錯,而經常也會導致嚴重的安全洩漏問題。→

很不幸的,像這樣的程式碼幾乎可以說是觸處皆是,然而這樣的程式碼卻很容易造成致命的錯誤,甚至往往是資安漏洞的根源。

用library string 比用 C-Style string更安全也更有效率(性能也更好)

頁124

1:43:10

練習3.37

1:58:30

const char ca[] = { 'h','e','l','l','o' };

const char* cp = ca;

while (*cp) {

cout << *cp << endl;

++cp;

}

會陷入無窮迴圈。除非在記憶體中碰到使*cp=false(即*cp='\0';'\0'即null)才會出迴圈

練習3.38

2:10:20

練習3.39

bool compareStrEqual(string str,string str1) {

if (str==str1)

{

return true;

}

else

{

return false;

}



}



以下就已經是C-Style了。就是把字串表示成字元來運算,對待字串,就好像處理字元陣列一樣,所以離不開指標pointer。

bool compareStrEqual() {

char cstr[]("天下為公");

char cstr1[] ("天0下為公");

char* p = cstr;

char* p1 = cstr1;

while (p<end(cstr))

{

if (*p!=*p1)

{

return false;

}

else

{

++p;

++p1;

}

}

return true;





}



bool compareStrEqual() {

char cstr[]("天下為公");

char cstr1[] ("天下為公");

if (strcmp(cstr,cstr1)!=0)

{

return false;

}

else

{

return true;

}

}

上列字串字面值(string literal)初始化的陣列的會自動帶上null terminated作為被初始化陣列的最後元素;但是如下若用串列初始化(list initialization)則一定要記得自己手動加上null為最末元素才行。

bool compareStrEqual() {

char cstr[]{'1','2','3','\0'};

char cstr1[]{ '1','2','3','\0' };

if (strcmp(cstr,cstr1)!=0)

{

return false;

}

else

{

return true;

}

}

練習3.40

3:2:12

string compareStrEqual() {

char cstr[]{"曾經滄海難為水"};

char cstr1[]{"除卻巫山不是雲"};//當用字串字面值(string literal)初始化一個字元陣列,就自動幫我們補上最後一個元素null了

constexpr unsigned sz = sizeof(cstr) / sizeof(*cstr) +

sizeof(cstr1) / sizeof(*cstr1) + 1;//確實可以藉由constexpr來定義一個由運算式(變數)運算出來的值成為常值

char cstr2[sz];

strcpy_s(cstr2, cstr);//在Visual Studio的環境下,不允許用不帶「_s」的函式,除非要用一些特定的表述法(暫未瞭)

strcat_s(cstr2, ",");

strcat_s(cstr2, cstr1);

string str{ cstr2 };//只要是字元陣列(character arrays)就可以直接轉換成字串(字元字串)

return str;//str="曾經滄海難為水,除卻巫山不是雲"

}

3.5.5. Interfacing to Older Code

銜接舊的C++程式碼

Mixing Library string s and C-Style Strings

3:43:20

3:47:00 字串字面值(string literal)與string是不同型別的東西,因為字串字面值(string literal)就是一個帶有null-terminated的字元陣列(character arrays)

字串字面值(string literal)看起來像是一個字串,其實就是一個帶有null-terminated的字元陣列(character arrays),就好像我們說在指名/具名操作一個陣列時,其實是在操作該陣列第一個元素的指標



3:56:00 string下的c_str成員函式

是用來把字串string轉成帶有null結尾的字元陣列(character arrays)

c_str的意思是傳回一個C-styel character string。

頁125

4:8:30

4:12:00 只要string值改變,其c_str成員函式產生的字元陣列(character arrays)當然也會隨之失效了。

4:16:00

WARNING

If a program needs continuing access to the contents of the array returned by str(), the program must copy the array returned by c_str.

Using an Array to Initialize a vector

4:19:00

我們也沒辦法用一個vector去初始化一個陣列



Advice: Use Library Types Instead of Arrays

最好是用程式庫型別取代陣列



3.6. Multidimensional Arrays

4:41:50 4:43:00

嚴格說來,C++並沒有所謂的多維陣列

陣列的陣列(陣列所構成的陣列,5:12:00即陣列的元素是陣列)就是多維陣列

頁126

4:46:33

練習3.41

string compareStrEqual() {

int iarr[]{1,2,3,4,5,6};

vector<int>ivec(begin(iarr),end(iarr));//用陣列將vector初始化

vector<int>ivec1(begin(iarr) + 1, iarr + 5);//不必取用整個陣列大小

return "";

}

練習3.42

vector<int>ivec{2,3,4,5,6,7};

int iarr[6];

int* p = iarr;

for (vector<int>::iterator i = begin(ivec); i != end(ivec); ++i)

{

*p = *i; ++p;

}

for (auto i : iarr)

{

cout<<i<<" ";

}

cout << endl;

5:11:10

5:20:20

There is no limit on how many subscripts are used.

定義中的[]仍是叫下標(subscript)

That is, we can have an array whose elements are arrays of elements that are arrays, and so on.

也就是說,我們可已有一個陣列其元素是陣列,而該陣列的元素也是 陣列,依此類推。

也就是說,我們可以有一個陣列其元素是陣列,而該陣列的元素也是陣列,依此類推。

Initializing the Elements of a Multidimensional Array



頁127

5:33:40

Subscripting a Multidimensional Array

5:38:10

留言

熱門文章