Динамическое распределение передачи по значению (C90) [дубликат]

Вы можете использовать массив указателей на (однородные) данные элемента, чтобы включить двойной интерфейс с именем-членом (например, x.data) и массивом-индексом (например, x [idx]).

#include <cassert>
#include <cstddef>

struct vector3 {
    float x;
    float y;
    float z;

    float& operator[](std::size_t idx) {
        static float vector3::*component[3] = {
            &vector3::x, &vector3::y, &vector3::z
        };
        return this->*component[idx];
    }
};

int main()
{
    vector3 v = { 0.0f, 1.0f, 2.0f };

    assert(&v[0] == &v.x);
    assert(&v[1] == &v.y);
    assert(&v[2] == &v.z);

    for (std::size_t i = 0; i < 3; ++i) {
        v[i] += 1.0f;
    }

    assert(v.x == 1.0f);
    assert(v.y == 2.0f);
    assert(v.z == 3.0f);

    return 0;
}
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 в 17:39
поделиться

Это не изменит фактическое значение 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 в 17:39
поделиться

Если вы хотите изменить содержимое переменной в функции в 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 в 17:39
поделиться

Для примитивного типа данных, такого как 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 в 17:39
поделиться

В 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 в 17:39
поделиться
Другие вопросы по тегам:

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