2016-06-05 3 views
0

Я пытаюсь понять разницу между проходом по значению и передачи по ссылке, и я подумал, что я, наконец, понимаю, пока я не видел этот код:Почему это проходит по значению?

void change(char *p1) 

{ 
    p1="new"; 
} 

int main() 

{ 
    char *txt1=(char*)malloc(200*sizeof(char)); 

    txt1="original"; 
    printf("before :%s\n",txt1); 
    change(txt1); 
    printf("after :%s\n",txt1); 

} 

ли не передавая адрес? а затем изменить его и указать, что он указывает на другое место?

Выход:

перед: оригинал

после: оригинал

Почему?

+2

Технически C не ничего, кроме пройти по стоимости поддержки. –

+0

@JoachimPileborg: «Технически»? В каком аспекте он поддерживает передачу по ссылке больше, чем любой другой язык, дополняющий формулировку? – Olaf

+0

C, C++, Java и любой язык, который я когда-либо слышал о том, что использует pass by value. Но вы можете передавать ссылки (или указатели) по значению, что делает его несколько запутанным. – alain

ответ

2

Там нет проход по ссылке у C. параметров в функцию передаются с использованием передачи по значению. То есть, p1 сам передается по значению. Вы можете изменить содержимое адреса памяти, на которое указывает p1 (*p1) от вызываемой функции, а не p1.

Чтобы уточнить, для изменения содержимого переменной var вам необходимо передать адрес var, поэтому, если вы хотите изменить сам указатель, вам необходимо передать адрес указателя на функцию.

Это сказало, please see this discussion on why not to cast the return value of malloc() and family in C.

2

Адрес: как стоимость. Чтобы измененная локальная переменная вызывала изменение адреса, передайте адрес , что следует изменить.

#include <stdio.h> 

void change(char **p1) 

{ 
    *p1="new"; 
} 

int main(void) 

{ 
    char *txt1; /* no causing memory leak */ 

    txt1="original"; 
    printf("before :%s\n",txt1); 
    change(&txt1); 
    printf("after :%s\n",txt1); 

} 
1

По вызову функции change(txt1);, txt1 передается по значению. Он копируется в параметр p функции change. Это делает pi указывает на ту же строку, что и txt1. Когда новая строка назначается p1, тогда p1 меняет направление на эту строку, а txt1 указывает на предыдущую.

этот случай очень похож на

char *s1 = "String"; 
char *s2 = s1;  // Both s1 and s2 points to same string 
s2 = "Another string" // Now s2 points to "Another string" while s1 pointing to "String". 

Помимо этого ваш код вызывает утечку памяти. Он должен быть похож на

char *txt1=(char*)malloc(200*sizeof(char)); 
strcpy(txt1,"original"); 
1

Проложить по ссылке и пройти по значению. Pass By Reference and Pass By value.

+0

Hahahaaa ............... Brilliant.: D – haccks

+0

За исключением того, что в C. нет (например, «pass by reference»). (-: – user3078414

+0

Я попытался определить концепцию ;) –

1

Вот пример, который я использовал ранее. Примут следующие две функций:

void foo(T *p) // where T is an arbitrary data type 
{ 
    *p = new_value(); // write new value to the thing p points to 
} 

void bar(void) 
{ 
    T var; 
    foo(&var); // write new value to var 
} 

Для функции foo обновить содержимое var (объекта типа T) мы должны передать указатель на var (типа T *).

Если заменить T с типом указателя P *, то приведенный выше код становится

void foo(P **p) 
{ 
    *p = new_value(); // write new value to the thing p points to 
} 

void bar(void) 
{ 
    P *var; 
    foo(&var); // write new value to var 
} 

Семантика точно так же; мы хотим, чтобы foo, чтобы написать новое значение var, поэтому мы передаем указатель на var. Это просто, что в этом случае var уже является типом указателя, поэтому мы завершаем передачу указателя на указатель.

В принципе, для foo обновить содержимое var, вы должны пройти выражение&var в качестве аргумента, то есть тип формального параметра p всегда будет иметь еще один уровень косвенности, чем тип var.

Type of var  Type of &var  Type of p 
-----------  ------------  --------- 
      T    T *   T * 
     T *    T **   T ** 
     T **    T ***   T *** 

т.д.

Смежные вопросы