程式設計疑難點

2021-06-29 06:27:25 字數 3395 閱讀 4764

下面的博文對於理解引數的傳遞和二級指標有幫助

自己補充一部分:

void change_val(char *p) 

; // [2]

p = new_val; //[3] 此處發生引數拷貝,用p_copy代替p,即用p_copy指標指向了new_val,為改變p所指向的值

printf("fun: address of p : 0x%x, content of p: %d \n",p,*p);

return; // [4]

} void change_val2(char *p)

; // [2]

memcpy(p, new_val, 3); //此處未發生引數拷貝,而是記憶體拷貝

printf("fun: address of p : 0x%x, content of p: %d \n",p,*p);

return;

}void change_val(char **p)

; // [2]

* p = new_val; //*p == *(&q),即&q所指向的值,即q的位址所指向的值,即q本身。

//**p == *q

return; // [3]

} char val[3] = ;

char *p = val; // [1]

change_val(&p);

void f(int **p);

你可以這樣呼叫f

f(b);

int * 是指向int型別的指標;

int *,也即(int ) ,是指向int 型別的指標,也就是指向指標的指標;

int,也即(int) ,是指向int**型別的指標,也就是指向指標的指標的指標;

struct *** *,是指向struct ***型別的指標;

其實,說這麼多,只是希望大家在看到指標的時候,不要被int *這樣的東西嚇到,就像前面說的,指標就是指向某種型別的指標,我們只看最後乙個*號,前面的只不過是type型別罷了。

函式在傳參過程中,是乙個內容的拷貝過程,而每個函式都會有自己的棧空間來存放區域性變數,所以,形參和實參是不同的記憶體單元。通俗點講,就是,你改變他們其中乙個的值,另乙個的值不會改變。

傳遞的引數是個指標的時候,就可以改變實參的值。當傳遞到形參時,進行指標拷貝,不管指標怎麼拷貝,只要操作指標所指向的值,那麼實參都會被改變。(形參就是指標所指向的值)。

void change_val(char **p)  

; *p = new_val;

return;

} char val[3] = ;

char *p = val;

change_val(&p);

p是指標,我現在要改變p所指向的記憶體的值,那麼我應該傳入p的位址進行操作。而且需要操作p本身,即操作傳入的p的位址所指向的內容,即*p。

void change_val(int

*p,int

*q)int

x = 1,y = 2;

fun(&x,&y);

補充:當定義的不是乙個指標時(int a;),傳給某個函式,而這個函式需要修改傳入引數的值,即內容,則應該傳入改引數的位址,然後在函式內部去修改傳入引數所指向的值。

而當定義乙個指標(int *p),傳給某個函式,而這個函式需要修改這個指標本身,即p,那麼我們應該傳入指標本身(p)的位址。

int cof[a][b][c][d];

cof[e][f][g][h]的位址應是:cof + sizeof(int)* e* b* c* d + sizeof(int)* f* c* d + sizeof(int)* g* d +sizeof(int)*h

如果已經知道了陣列的大小,就用

int x[100][100][100][2];

在宣告它的標頭檔案用 extern int x[100][100][100][2];

在定義它的.cpp檔案中用 int x[100][100][100][2];

c和c++程式設計師都應該這麼寫程式。訪問速度快,記憶體占用小。

我們算個帳,用我的辦法是100*100*100*2*sizeof(int) 在32位和64位編譯器出來是8百萬位元組;

如果用你的辦法是100*100*100個指標,最終的int個數與我的方法相同,前面1百萬個指標(32位編譯器出來是4百萬位元組,64位編譯器出來是8百萬位元組,50-100%的overhead, 一下就把記憶體占用增加了老多。

訪問的時候,每個最終的整數要做3次indirection, 對比我的方法的1次indrection. c/c++程式設計師不可以隨便忽略這樣的差異。not without a compelling reason.

如果你確定你就是要用這個方法,**可以這樣寫(c**,當然c++下也沒問題)

// user to free the returned pointer

int ****gen_4_dimensional_array()

}return (int****)p;

}

ref:

問題一:

double i;

for(i = 0;i != 10;i+=0.1)

return

count;

}

第一種方法:

返回乙個指向陣列的指標,例如char ( *retarray() )[10]宣告了乙個函式retarray,該函式可以返回指向具有10個char元素的陣列

例子如下:

#include 

#include

int (*retarray())[10]

return a;

}int main()

第二種方法,使用結構體作為返回值來傳遞陣列:

struct array

;struct array test(char *tmp)

第三種方法,使用靜態變數,返回指標

多型疑難點

多型 使用父類作為方法的形參 使用父類作為方法的返回值 父類作為方法的形參 通俗的說就是,只通過操作父類就可以達到操作子類的效果。使用的原理是向上轉型 父類的引用指向子類物件。自動進行型別轉換。注意 1 此時通過父類引用變數呼叫的方法是子類覆蓋或繼承父類的方法,不是父類的方法。再說,我們在父類裡也只...

疑難點積累(二)

參考文章 這裡有詳細的驗證和說明 1 timer會對它的target進行retain,直到timer自己失效為止。對重複執行的timer必須呼叫invalidate才能停止timer,讓timer失效。2 timer並不是一種實時機制,不是你指定1s後執行,1s後就會立即執行。當執行緒空閒的時候,t...

面試疑難點解析

list,set,map,有什麼區別?list和set實際上市實現了collection介面,那麼collection介面的原理你能簡單描述一下嗎?list介面可以插入多個null值,並且重複值,而且list是乙個有序的集合。set是乙個不可重複的集合,裡面的元素都只出現,最多隻出現1次,並且set...