Вы можете использовать массив указателей на (однородные) данные элемента, чтобы включить двойной интерфейс с именем-членом (например, 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;
}
В 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 ++, альтернативный способ заключается в том, чтобы изменить функцию, чтобы принять ссылку на указатель.
Это не изменит фактическое значение 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;
}
Если вы хотите изменить содержимое переменной в функции в 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;
}
Для примитивного типа данных, такого как 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;
}
В 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