Вызов по значению может изменить значение для основной программы - PullRequest
0 голосов
/ 05 июля 2019

Рассмотрим следующие программы:

void f2 ( int * a, int * b) {   
               int c; 
               c = * a;
               *a = *b;
               *b = c; 
} 
int main () { 
        int a = 4, b = 5, c = 6; 
        f2 (&b, &c); 
        printf ("%d", c - a - b);  
 }

Здесь значения b и c меняются местами.

И еще один код:

# include <stdio.h>
void mystery (int *ptra, int *ptrb) {  
     int *temp; 
     temp = ptrb;  
     ptrb = ptra; 
     ptra = temp; 
} 
int main () { 
    int a = 2016, b=0, c= 4, d = 42; 
    mystery (&a, &b);
    if (a < c) 
          mystery (&c, &a); 
    mystery (&a, &d); 
    printf("%d\n", a); 
}

Здесь, несмотря на то, что вызов функции того же типа существует, значения любой переменной в программе main() не изменяются.

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

Во второй программе указатель подкачки означает, что адрес также поменяется местами. Правильно?? Но это не влияет на стоимость. В 1-й программе адрес и указатель меняются местами, а в то же время значения также меняются местами. Но почему ??

Я также хочу знать, где вызов по значению может изменить значение программы main () (с функцией возврата или без нее) ??

Ответы [ 3 ]

3 голосов
/ 05 июля 2019

Во второй программе указатель перестановки означает, что адрес также обменивать. Правильно?? Но это не влияет на стоимость. Пока в 1-й программе , адрес и указатель поменялись местами и в то же время значения также местами. Но почему ??

Поскольку

void mystery (int *ptra, int *ptrb) {  
     int *temp; 
     temp = ptrb;  
     ptrb =ptra; 
     ptra = temp; 
}

Вышеуказанная программа меняет содержимое ptra и ptrb, а не содержимое объектов, на которые указывают ptra и ptrb, поскольку ptra и ptrb являются локальными для функции mystery.


Для наглядного представления.

Рассмотрим a и b, хранящиеся по адресу 100 и 200.

После mystery (&a, &b); звонка.

ptra будет указывать на a, сохраняя в нем 100. и ptrb будет указывать на b, сохраняя в нем 200.

     ptra       100
   +-----+     +---+
   | 100 |     | 1 | 
   +-----+     +---+
     ptrb       200
   +-----+     +---+
   |200  |     | 2 | 
   +-----+     +---+

Когда функция заканчивает выполнение.

ptra будет указывать на b, сохраняя 200 в нем. и ptrb будет указывать на a, сохраняя в нем 100.

    ptra        100
   +-----+     +---+
   | 200 |     | 1 | 
   +-----+     +---+
    ptrb        200
   +-----+     +---+
   |100  |     | 2 | 
   +-----+     +---+
2 голосов
/ 05 июля 2019

В f2 в первой программе указатели разыменовываются для изменения того, на что указывают эти указатели, так что b и c в функции main модифицируются. Напротив, mystery во второй программе только меняет значения локальных переменных ptra и ptrb, что не влияет на переменные в main.

Итак, это:

ptrb = ptra; 

Назначено значение одного указателя другому (оба являются локальными для msytery), в то время как это:

*a = *b;

Изменяет значение того, на что один указатель указывает на , на значение, на которое другой указатель указывает на , а именно a и b в main.

Еще один способ думать об этом с домами и их жителями:

    ______        _____         ______       ______
   /______\      /______\      /______\     /______\
 2 |Smith |    4 |Jones |    6 | Bond |   8 | Solo |
   --------      --------      --------     --------

Первая программа гласит: «поменять жильцов двух домов»:

    ______        _____         ______       ______
   /______\      /______\      /______\     /______\
 2 |Smith |    4 | Bond |    6 |Jones |   8 | Solo |
   --------      --------      --------     --------

В то время как второй говорит "поменяйте местами номера на домах":

    ______        _____         ______       ______
   /______\      /______\      /______\     /______\
 2 |Smith |    6 |Jones |    4 | Bond |   8 | Solo |
   --------      --------      --------     --------
1 голос
/ 05 июля 2019

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

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

...