2014-09-03 134 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