Double pointer · parallel_processing

文章推薦指數: 80 %
投票人數:10人

陣列的指標(pointer to array) 以及二維陣列(two dimensional array) 的基本用法: ... 簡單的說,它是一個一維陣列,每個元素放的是char *指標,指向字串"Hello"與"C". parallel_processing Introduction 程序/行程(Process) 平行處理系統類別 MPI(Messagepassinginterface) MPICH安裝與設定 點對點通訊 集合通訊 Communicator One-sidedcommunication TORQUE OpenMP OpenMP設定 pthread ApacheSpark Spark安裝與設定 RDD介紹 基本程式設計 HDFS MapReduce介紹 CUDA 安裝(installation) 第一個程式 PyCUDA Theano Tensorflow XORproblem Cython 編譯 平行處理 PEP numpy Pandas C語言語法 Clibrary Pointer Doublepointer Functionpointer Struct Memoryleak C++參考 C++物件 C++樣版 x86函式調用協定 編譯器參數 cmake Pythonclass設計 nosetest py.test BLASlibrary Linpackbenchmark PoweredbyGitBook Doublepointer 雙層指標(doublepointerorpointerofpointer) intnum=123; int*pr2=# int**pr1;=&pr2; 雙層指標(doublepointer),這種資料格式很容易和指標陣列、陣列的指標、以及二維陣列三種型態混淆。

會有此不同解釋的差異是因為*運算子的優先權 int*arr1[10];//長度為10的指標陣列 int*(arr2[10]);//同上,長度為10的指標陣 int(*arr3)[10];//指標指向長度為10的陣列,若有5列(5個指標)時,等價於intarr3[5][10]; 雙層指標基本用法: int**ppData=NULL; int*pData=NULL; intdata=0; ppData=&pData; pData=&data; **ppData=10;//在變數data內存入數值資料10 陣列的指標(pointertoarray)以及二維陣列(twodimensionalarray)的基本用法: 陣列的指標是指有許多指標,每個指標指向固定長度的陣列 /*pointertoarrayof20integers *這邊*pAry是指向每個row的第一個元素,而每個row有20個元素 *因此pAry[i][j]等於*(*(pAry+i)+j) */ int(*pAry)[20]; intx[10][20]; ppData=x;//ERROR:cannotconvertint[20]*toint** pAry=x;//OK:sametype pAry[5][10]=100;//將數值100置於變數x[5][10]之內 //等價於*(*(pAry+5)+10)=100 指標陣列(pointerarray)的基本用法 指標陣列為型態為指標的陣列 int*ptrAry[20];//pointerarray,即為20個指標的array,如同doublearr[20]; ppData=ptrAry;//OK:sametype ppData[13]=&data;//將變數data的位址存放到變數ptrAry[13]中 cdecl解釋 上述複雜的情形,可使用cdecl程式解釋,首先安裝sudoapt-getinstallcdecl 進入cdecl環境中,輸入 cdecl>explainint*arr1[8]; declarearr1asarray8ofpointertoint cdecl>explainint(*arr2)[8] declarearr2aspointertoarray8ofint cdecl>explainint*(arr3[8]) declarearr3asarray8ofpointertoint 二維陣列和字串陣列 二維陣列和字串陣列是個很類似的東西。

/*names1為字串陣列,names2為二維陣列*/ char*names1[]={"Hello","C"};//sizeof(names1)=8 charnames2[][6]={"Hello","C"};//sizeof(names2)=12 names1是一個字串陣列,簡單的說,它是一個一維陣列,每個元素放的是char*指標,指向字串"Hello"與"C" 重點是,"Hello"與"C"這兩個字串並不存在陣列裡,而是存在記憶體的其他地方。

也可解釋為這個兩個指標所形成的陣列。

names2是一個二維陣列,簡單的說,字串是儲存在陣列裡,也由於他是儲存在陣列裡,所以必須考慮到最長的字串長度,雖然第二個元素"C"只有1byte再加上'\0'共2byte,"Hello"加上'\0'共6byte,為了考慮最長字串6byte,導致names的column長度要宣告到6byte,很明顯地,這對第一個元素"C"浪費了4byte,但字串陣列就沒這個缺點。

指標在函數中改方向時必須以doublepointer參數傳遞 如要在函式裡面改變變數a的值時,引數必須為pointer,然後傳入&a一樣。

如果要在函式裡面改變pointerp的值,則引數必須為doublepointer,然後傳入&p。

voidfoo1(int*q,int&v){ q=&v; } voidfoo2(int**q,int&v){ *q=&v; } intmain(){ inti=10,j=20; int*p=&i; foo(p,&j); printf("*p=%d\n",*p);//p=10,值沒有改變 foo2(&p,&j); printf("*p=%d\n",*p);//p=20; return0; } 在foo1裡面,我們有一個local的pointerq。

當呼叫foo1時,實際上我們把p的內容,拷貝給q。

所以q也指向i。

譬如說,&i的位址假設是0×1234,p裡面的內容就是0×1234。

所以呼叫foo1的時候,p的內容被拷給q,而p被丟入stack中。

當你改變q的值時,p並沒有受到影響。

所以當程式返回之後,p的值還是0×1234。

指標以函數參數傳遞時,仍是copybyvalue。

在foo2裡面,情況則不一樣。

傳入foo2裡面的是p的位址。

所以當你改變*q的時候,會改變p的指向。

使用doublepointer接住傳遞來的位址。

Pointer與多維陣列 array並非pointer,但array可以自動轉型成pointer,這也是array傳進function後變成pointer的理論基礎 inta[2][4]={{1,3,5,7},{2,4,6,8}}; 陣列表示法 值 連續記憶體表示法 陣列索引值轉換表示法 a[0][0] 1 **a ((a+0)+0) a[0][1] 3 (a+1) ((a+0)+1) a[1][0] 2 (a+4) ((a+1)+0) a[1][3] 8 (a+7) ((a+1)+3) 二維陣列 二維陣列使用陣列名稱與兩個索引值來指定存取陣列元素,這兩個索引值都是由0開始。

C語言存放二維或維度更高的陣列是以row-major方式儲存(fortran是columnmajor) ccompiler在編譯時會將高維的陣列轉回一維。

以二維陣列arr有N_ROW列,N_COL行,則arr[idx][jdx]以row-major轉回一維索引即為idx*N_ROW+jdx. #include #defineROW5 #defineCOLUMN10 intmain(void){ intmaze[ROW][COLUMN]; for(inti=0;i intmain(){ inta[3][5]; int(*ptr)[5]=a;//指向每一個列的開頭元素,每列5個元素。

printf("alocation:%p\n",a); printf("a[0][0]:%p\n",&a[0][0]); printf("ptr[0]:%p\n",ptr[0]); printf("a[1][0]:%p\n",&a[1][0]); printf("ptr[1]:%p\n",ptr[1]); return0; } //output alocation:0x7ffd8e57cb50 a[0][0]:0x7ffd8e57cb50 ptr[0]:0x7ffd8e57cb50 a[1][0]:0x7ffd8e57cb64 ptr[1]:0x7ffd8e57cb64 return0; } 函數參數必須指定column的長度 voidfoo1(intx[][]){//編譯成功,但Compiler不知如何翻譯,還是用int*x自己計算地址比較好 x[2][2]=0;//編譯錯誤!,Compiler不知如何翻譯 } voidfoo2(intx[][3]){//Compiler知道如何翻譯 x[1][1]=0;//Compiler知道要翻成*(x+1*3+1) } voidfoo3(intx[2][3]){//Compiler知道如何翻譯 x[1][1]=0;//Compiler知道要翻成*(x+1*3+1) } voidfoo4(intx[3][]){//編譯錯誤 } voidfoo5(int*x){//反正只能傳pointer *(x+1*3+1)=0; } intmain(){ intm[2][3]; int*p; intk[4][4]; foo2(m); foo2(p);//Compilerwarning,incompatiblepointertype foo3(k);//Compilerwarning,incompatiblepointertype foo5(m);//Compilerwarning,incompatiblepointertype foo5(p); foo5((int*)m);//強迫轉型,Compiler就不會抱怨了 } 動態配置二維陣列 非連續記憶體:缺點是memoryfragment。

constintsizex=2; constintsizey=3; intx,y; int**ia=(int**)malloc(sizey*sizeof(void*)); for(y=0;y!=sizey;++y) ia[y]=(int*)malloc(sizex*sizeof(int*)); //operations for(y=0;y!=sizey;++y) free(ia[y]); free(ia); 連續記憶體 //此版本仍然釋放二次,不完善 constintsizex=3; constintsizey=2; intx,y; int**ia=(int**)malloc(sizey*sizeof(void*)); //將第二個陣列所需的記憶體一次malloc() int*iax=(int*)malloc(sizey*sizex*sizeof(int*)); for(y=0;y!=sizey;++y,iax+=sizex) ia[y]=iax; ... free(ia[0]); free(ia); constintsizex=3; constintsizey=2; intx,y; int**ia=(int**)malloc(sizey*sizeof(void*)+sizey*sizex*sizeof(int*)); int*iax=(int*)(ia+sizex); for(y=0;y!=sizey;++y,iax+=sizex) ia[y]=iax; ... free(ia); 二維陣列非連續配置記憶體 C語言可以使用arraystyle的方式將二維陣列傳入函數,可以同時提供rowsize與columnsize,也可省略rowsize只提供columnsize。

C語言可以將二維陣列用pointer如傳遞一維陣列方式傳入函數,在某些場合使用一維陣列操作方式可能更加方便。

當C語言的二維陣列以pointer型態傳入函數時,必須要使用包含columnsize的一維陣列的pointer。

//因為n_row與n_col都是變數,所以必須使用此方式才能傳進function voidsub(int**matrix,introw_size,intcol_size); /*如果n_row與n_col為定值時,可使用以下的函式簽名 voidsub(intmatrix[][n_col]); orvoidsub(int(*matrix)[n_col]); 注意仍不可指定n_row之值 */ intmain(){ intx,y; scanf("%d%d",&x,&y); int**matrix=calloc(y,sizeof(int*)); for(inti=0;i



請為這篇文章評分?