第四章 陣列和指標

2021-06-04 16:43:37 字數 4248 閱讀 7543

由於陣列和指標這部分知識比較深奧,本菜鳥決定將c和c++的指標部分的知識點全歸到c語言部分來整理,所以這裡就只總結一些題目。

下列陣列的值是什麼?

string sa[10];

int ia[10];

int main()

【解答】

sa 和sa2 為元素型別為string 的陣列,自動呼叫string 類的預設建構函式將各元素初始化為空字串;ia 為在函式體外定義的內建陣列,各元素初始化為0;ia2 為在函式體內定義的內建陣列,各元素未初始化,其值不確定。

如何初始化陣列的一部分或全部元素?

【解答】

定義陣列時可使用初始化列表(用花括號括住的一組以逗號分隔的元素初值)來初始化陣列的部分或全部元素。如果是初始化全部元素,可以省略定義陣列時方括號中給出的陣列維數值。如果指定了陣列維數,則初始化列表提供的元素個數不能超過維數值。如果陣列維數大於列出的元素初值個數,則只初始化前面的陣列元素,剩下的其他元素,若是內建型別則初始化為0,若是類型別則呼叫該類的預設建構函式進行初始化。字元陣列既可以用一組由花括號括起來、逗號隔開的字元字面值進行初始化,也可以用乙個字串字面值進行初始化。

列出使用陣列而不是vector 的缺點。

【解答】

與vector 型別相比,陣列具有如下缺點:陣列的長度是固定的,而且陣列不提供獲取其容量大小的size 操作,也不提供自動新增元素的push_back 操作。因此,程式設計師無法在程式執行時知道乙個給定陣列的長度,而且如果需要更改陣列的長度,程式設計師只能建立乙個更大的新陣列,然後把原陣列的所有元素複製到新陣列的儲存空間中去。與使用vector 型別的程式相比,使用內建陣列的程式更容易出錯且難以除錯。

下面提供了兩種指標宣告的形式,解釋寧願使用第一種形式的原因:

int *ip; // good practice

int* ip; // legal but misleading

【解答】

第一種形式強調了ip 是乙個指標,這種形式在閱讀時不易引起誤解,尤其是當乙個語句中同時定義了多個變數時。

已知一指標p,你可以確定該指標是否指向乙個有效的物件嗎?如果可以,如何確定?如果不可以,請說明原因。

【解答】

無法確定某指標是否指向乙個有效物件。因為,在c++語言中,無法檢測指標是否未被初始化,也無法區分乙個位址是有效位址,還是由指標所分配的儲存空間中存放的不確定值的二進位制位形成的位址。

下列**中,為什麼第乙個指標的初始化是合法的,而第二個則不合法?

int i = 42;

void *p = &i;

long *lp = &i;

【解答】

具有void*型別的指標可以儲存任意型別物件的位址,因此p 的初始化是合法的;而指向long 型物件的指標不能用int 型物件的位址來初始化,因此lp的初始化不合法。

解釋指標和引用的主要區別。

【解答】

使用引用(reference)和指標(pointer)都可間接訪問另乙個值,但它們之間存在兩個重要區別:(1)引用總是指向某個確定物件(事實上,引用就是該物件的別名),定義引用時沒有進行初始化會出現編譯錯誤;(2) 賦值行為上存在差異:給引用賦值修改的是該引用所關聯的物件的值,而不是使該引用與另乙個物件關聯。引用一經初始化,就始終指向同乙個特定物件。給指標賦值修改的是指標物件本身,也就是使該指標指向另一物件,指標在不同時刻可指向不同的物件(只要保證型別匹配)。

下列程式段實現什麼功能?

int i = 42, j = 1024;

int *p1 = &i, *p2 = &j;

*p2 = *p1 * * p2;

*p1 *= *p1;

【解答】

該程式段使得i 被賦值為42 的平方,j 被賦值為42 與1024 的乘積。

已知p1 和p2 指向同乙個陣列中的元素,下面語句實現什麼功能?

p1 += p2 – p1;

當p1 和p2 具有什麼值時這個語句是非法的?

【解答】

此語句使得p1 也指向p2 原來所指向的元素。原則上說,只要p1 和p2 的型別相同,則該語句始終是合法的。只有當p1 和p2 不是同型別指標時,該語句才不合法(不能進行-操作)。但是,如果p1 和p2 不是指向同乙個陣列中的元素,則這個語句的執行結果可能是錯誤的。因為-操作的結果型別ptrdiff_t 只能保證足以存放同一陣列中兩個指標之間的差距。如果p1 和p2 不是指向同乙個陣列中的元素,則-操作的結果有可能超出ptrdiff_t 型別的表示範圍而產生溢位,從而該語句的執行結果不能保證p1 指向p2 原來所指向的元素(甚至不能保證p1 為有效指標)。

解釋下列5 個定義的含義,指出其中哪些定義是非法的:

(a) int i;

(b) const int ic;

(c) const int *pic;

(d) int *const cpi;

(e) const int *const cpic;

【解答】

(a) 合法:定義了int 型物件i。

(b) 非法:定義const 物件時必須進行初始化,但ic 沒有初始化。

(c) 合法:定義了指向int 型const 物件的指標pic。

(d) 非法:因為cpi 被定義為指向int 型物件的const 指標,但該指標沒有初始化。

(e) 非法:因為cpic 被定義為指向int 型const 物件的const 指標,但該指標沒有初始化。

下列哪些初始化是合法的?為什麼?

(a) int i = -1;

(b) const int ic = i ;

(c) const int *pic = ⁣

(d) int *const cpi = ⁣

(e) const int *const cpic = ⁣

【解答】

(a) 合法:定義了乙個int 型物件i,並用int 型字面值-1 對其進行初始化。

(b) 合法:定義了乙個int 型const 物件ic,並用int 型物件對其進行初始化。

(d) 不合法:cpi 是乙個指向int 型物件的const 指標,不能用const int型物件ic 的位址對其進行初始化。

解釋下列兩個while 迴圈的差別:

const char *cp = "hello";

int cnt;

while (cp)

while (*cp)

【解答】

兩個while 迴圈的差別為:前者的迴圈結束條件是cp 為0 值(即指標cp 為0值);後者的迴圈結束條件是cp 所指向的字元為0 值(即cp 所指向的字元為字串結束符null(即'\0'))。因此後者能正確地計算出字串"hello"中有效字元的數目(放在cnt 中),而前者的執行是不確定的。注意,題目中的**還有乙個小問題,即cnt 沒有初始化為0 值。

解釋strcpy 和strncpy 的差別在**,各自的優缺點是什麼?

【解答】

strcpy 和strncpy 的差別在於:前者複製整個指定的字串,後者只複製指定字串中指定數目的字元。strcpy 比較簡單,而使用strncpy 可以適當地控制複製字元的數目,因此比strcpy 更為安全。

第四章 陣列和指標

4.1 陣列 1 陣列的初始化 在函式體外定義的內建陣列,都初始化為0 在函式體內的內建陣列,均無初始化 顯示顯示初始化則可不必制定陣列的維數 初始化如果元素為類型別,則自動的條用該類預設的建構函式 2 特殊字元陣列 char ca c 會自動的在c 後新增乙個空的字元 o 而char ca2 ca...

第四章 陣列和指標

陣列 首先陣列的初始化不允許直接複製和賦值,陣列的元素的型別是size t型別,可以通過for size t ix 0 ix!array size ix 指標 指標的定義 int p 注意 在使用指標之前必須要初始化指標。並且對指標初始化的值應該使用如下四種值 1 0值常量表示式。例如和疑惑的0值得...

C Primer 第四章 陣列和指標

4.2指標的引入 1.指標變數的定義 string pstring 語句把pstring定義為乙個指向string型別物件的指標變數。或者也可以如下定義 string ps 如果需要再乙個宣告語句中定義兩個指標,必須在每個變數識別符號前再加符號 宣告 string ps1,ps2 4.指標可能的取值...