Установка значения в структуре, передача по значению вопроса? (C90) [дубликат]

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

struct foo {
    std::string a;
    std::string b;
};

Хорошо, теперь предположим, что у вас есть куча foo s в контейнере:

// key: some sort of name, value: a foo instance
std::map<std::string, foo> container;

Хорошо, теперь предположим, что вы загружаете данные из разных источников, но данные представляются одинаково (например, вам нужен тот же метод синтаксического анализа).

Вы могли бы сделайте что-то вроде этого:

void readDataFromText(std::istream & input, std::map<std::string, foo> & container, std::string foo::*storage) {
    std::string line, name, value;

    // while lines are successfully retrieved
    while (std::getline(input, line)) {
        std::stringstream linestr(line);
        if ( line.empty() ) {
            continue;
        }

        // retrieve name and value
        linestr >> name >> value;

        // store value into correct storage, whichever one is correct
        container[name].*storage = value;
    }
}

std::map<std::string, foo> readValues() {
    std::map<std::string, foo> foos;

    std::ifstream a("input-a");
    readDataFromText(a, foos, &foo::a);
    std::ifstream b("input-b");
    readDataFromText(b, foos, &foo::b);
    return foos;
}

. В этот момент при вызове readValues() будет возвращен контейнер с унисоном «input-a» и «input-b»; все клавиши будут присутствовать, а foos имеют либо a, либо b или оба.

23
задан Prakash Gautam 17 November 2012 в 15:41
поделиться

5 ответов

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

 void foo(int** p) {
      *p = 0;  /* set pointer to null */
 }
 void foo2(int* p) {
      p = 0;  /* makes copy of p and copy is set to null*/
 }

 int main() {
     int* k;
     foo2(k);   /* k unchanged */
     foo(&k);   /* NOW k == 0 */
 }

Если у вас есть возможность использовать C ++, альтернативный способ заключается в том, чтобы изменить функцию, чтобы принять ссылку на указатель.

29
ответ дан mathematician1975 26 August 2018 в 18:34
поделиться

Это не изменит фактическое значение p, потому что функция q in является локальной для этого, и изменение этой функции не будет отображаться в main, поэтому передайте адрес p вместо передачи p по значению

Используйте этот синтаксис ниже

  void change_adrs(int **q)
  {
  int * otheraddess;
  *q = otheraddress; 
  }

и называйте это change_adrs(&p);

Или у вас есть другой способ: изменить возврат тип функции и поймать возвращенный адрес.

int* change_adrs(int *q)
      {
      int * otheraddess;
      q = otheraddress;
      return q; 
      }


int main()
{
 p=change_adrs(p);
 return 0;
}
0
ответ дан Benjamin 26 August 2018 в 18:34
поделиться

Если вы хотите изменить содержимое переменной в функции в C, указатель также является своеобразной переменной, вы должны передать ее с помощью указателя или косвенной ссылки , используя всегда & адрес и * операторы разыменования. Я имею в виду, что * оператор всегда используется и предшествует при изменении значения переменной.

#include <stdio.h>
#include <stdlib.h>


void changeIntVal(int *x) {
    *x = 5;
}

void changePointerAddr(int **q) {
    int *newad;
    *q = newad;
}

void changePPAddr(int ***q) {
    int **dummy;
    *q = dummy;
}

int main() {
    int *p;
    int **pp;
    int *tempForPP;
    int a = 0;
    printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);


    p = &a;
    pp = &tempForPP;
    printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);

    changeIntVal(&a);        // ----
                             //    |---
    changePointerAddr(&p);   // ----  |---->  parts of what I mean
                             //    |---
    changePPAddr(&pp);       // ----

    printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);

    return 0;

}
2
ответ дан snr 26 August 2018 в 18:34
поделиться

Для примитивного типа данных, такого как int, двойные указатели не нужны. Вы можете писать непосредственно в адрес, где хранится int, обрабатывая его адрес как указатель вызываемой функции. Это не похоже на массив char («строка»), где размер указателя указывает на переменную, и поэтому вы должны использовать другой уровень косвенности при изменении его из вызываемой функции. Попробуйте следующее:

void foo(int *oldVal)
{
    int newVal = 99;    // or whatever you want
    *oldVal = newVal;
}

int main(int argc, char *argv[])
{
    int someVal = 0;
    foo(&someVal);      // we send its address to foo()

    printf("someVal is now %d.\n", someVal);

    return EXIT_SUCCESS;
}
1
ответ дан todkwxrtvwmzonunswam 26 August 2018 в 18:34
поделиться

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

void change(int **p, int *someOtherAddress)
{
    *p = someOtherAddress;
}

int a = 1, b = 2;
int *p = &a;

printf("*p = %d\n", *p);
change(&p, &b);
printf("*p = %d\n", *p);

Отправляет

*p = 1
*p = 2
10
ответ дан user 26 August 2018 в 18:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: