2014-09-03 83 views
-3
/*i am doing in main function*/ 
int main(void) 
{ 
//allocating memory 
double** p = malloc(ROWS * sizeof(double*)); 
    int i, j; 

    for (i = 0; i < ROWS; i++) 
    p[i] = malloc(COLS * sizeof(double)); 
// set every array element as 1 
    for (i = 0; i < ROWS; i++) 
    for (j = 0; j < COLS; j++) 
     p[i][j] = 1; 
//print array element 
    for (i = 0; i < ROWS; i++) 
    { 
    for (j = 0; j < COLS; j++) 
     printf("%f ", p[i][j]); 
    printf("\n"); 
    } 

    make5(ROWS, COLS, p); 
//here why this is changed??? 
    for (i = 0; i < ROWS; i++) 
    { 
    for (j = 0; j < COLS; j++) 
     printf("%f ", p[i][j]); 
    printf("\n"); 
    } 

    return 0; 
} 


/* and changing value in below function */ 
int make5(int r, int c, double **d) 
{ 
    int i, j; 
    /*changing value of received array*/ 
    for (i = 0; i < r; i++) { 
    for (j = 0; j < c; j++) { 
     d[i][j] = 5; 
    } 
    } 

    return 0; 
} 
+4

您還沒有詢問一個明確的問題。你已經包括了「這裏爲什麼會改變」,但不清楚你預期會發生什麼或爲什麼。沒有任何文字的問題絕不是一個好的起點。 – 2014-09-03 06:03:31

+0

爲什麼value的數組發生了變化,因爲在這裏我通過指針傳遞value.both指針** p和** d具有相同的類型。 – 2014-09-03 06:05:02

+0

並改變不同函數中的值,使用按值類型自變量調用,所以根據我的值不應該在調用函數(main)中反映 – 2014-09-03 06:07:26

回答

1

您通過值指針 - 但這只是一個指針。那說其中包含單個值的內存是。您make5功能實際上並不改變所有的參數(d)的價值 - 這將是這樣的:

d = malloc(...); 

傳址值是指更改參數值(p在這種情況下)被簡單地複製到參數(d)。函數的調用者不會看到參數的其他更改。這很好,因爲沒有改變參數。相反,你的函數改變d引用的內存的內容。這與p所引用的內存相同,因此您在調用該函數後打印這些值時會看到更改。 (在這種情況下,實際上存在兩個間接級別,因爲p的值說明了更多指針的位置,但原理相同。)

假設我將我的街道地址寫在一張紙上(p) 。我複印那張紙,並給你,稱爲副本d。我不在乎你對這張紙做的任何事情 - 但如果你訪問我的房子並用另一種顏色畫門,我會看到,因爲我的房子的街道地址仍然在我的一張紙。這張紙不包含我的房子 - 它只是告訴我如何到我家。同樣,指針並不包含所有的單個值 - 它只是告訴你如何到達它們。 (:foo(&my_variable) e.g):

+0

但是值應該在指針**副本中改變。而不是p指向的內存位置。因爲它是通過值傳遞不通過參數 – 2014-09-03 06:11:17

+1

@Akhandpratapsingh:我不明白你的意思。我認爲你應該修改你正在學習C的任何書籍/教程中的指針 - 你似乎將指針與它指向的內存內容混淆。如果您只使用單個指針而不是雙指針 - 您可能會發現它更簡單 - 應用完全相同的原則,但考慮更簡單。 – 2014-09-03 06:14:16

+0

你是說如果我有 int t = 100; int * pt_t =&t; func(pt_t); void func(int * foo){int a = 1000; * foo = &a ;} 應該更改值 – 2014-09-03 06:26:23

0

最簡單的辦法,除非你在他們前加上&在C中的所有變量都傳遞給函數的值。在您的代碼中,d是類型爲double**的變量,即包含雙倍數組矩陣的存儲位置的變量您正在向make5傳遞一個內存位置,而不是該內存位置的內容的副本。因此,make5正在重寫原始矩陣的內容。如果您想make5保留原始矩陣,則在make5中創建一個局部矩陣,並將原始矩陣複製到其中。

+0

但是我的問題是這個指針類型的d和p是相似的。都是** p和** d.so如果我們在make5中傳遞p內存位置,那麼它通過** d接收。它意味着在d點​​內存位置二維數組 那麼爲什麼值會發生變化? – 2014-09-03 06:38:04

+0

我的問題與我相似, int t = 100; int * pt_t =&t; FUNC(pt_t); void func(int * foo){int a = 1000; * foo = &a ;}應該改變數值 - – 2014-09-03 06:39:19

+0

換句話說吧。想象一下,指針是一個包含蘋果的包(在我們的例子中,蘋果是雙數)。傳遞函數的指針與將**包**給一個人相同。如果那個人從包裏吃了一個蘋果,當他把包還給我們時,我們會看到有一個蘋果丟失了。 **因爲我們把袋子交給了人**,所以包的內容已經改變了。我能做些什麼來防止該人改變包的內容?簡單:沒有給它。相反,我們會給他一個蘋果數量相同的袋子。 – Claudix 2014-09-03 07:03:37