Я искал бы это, но честно я не буду знать, где запустить, потому что я не знаю то, чем это называют. Я видел, что переменные передали функциям как это:
myFunction((void**)&variable);
Который путает heck из меня, вызывают всех тех, выглядят знакомыми мне; я только что никогда не видел, что они соединяют как этот прежде.
Что это значит? Я - newb так чем меньше жаргона, тем лучше, Спасибо!
Это приведение к указателю на указатель void
.
Вы часто наблюдаете это с такими функциями, как CoCreateInstance ()
в системах Windows.
ISomeInterface* ifaceptr = 0;
HRESULT hr = ::CoCreateInstance(CLSID_SomeImplementation, NULL, CLSCTX_ALL,
IID_ISomeInterface, (void**)&ifaceptr);
if(SUCCEEDED(hr))
{
ifaceptr->DoSomething();
}
Приведение преобразует указатель на указатель ISomeInterface
в указатель на указатель void
, чтобы CoCreateInstance ()
мог установить ifaceptr
] на допустимое значение.
Поскольку это указатель на указатель void
, функция может выводить указатели любого типа в зависимости от идентификатора интерфейса (например, IID_ISomeInterface).
Это приводит к преобразованию & variable
в void **
(то есть указатель на указатель на void
).
Например, если у вас есть что-то вроде
void myFunction(void** arg);
int* variable;
Это передает адрес переменной
(это то, что делает унарный- &
, он принимает адрес) в myFunction ()
.
void *
- это «указатель на что угодно». void **
- это еще один уровень косвенного обращения - «указатель на указатель на что-либо». По сути, вы передаете это, когда хотите, чтобы функция возвращала указатель любого типа.
& variable
принимает адрес переменной. переменная
уже должна быть своего рода указателем, чтобы это работало, но, вероятно, это не void *
- это может быть, скажем, int *
, поэтому адрес приведет к int **
. Если функция принимает void **
, вам необходимо привести к этому типу.
(Конечно, он должен действительно вернуть объект правильного типа, иначе вызывающий код не сработает, когда попытается использовать его неправильно.)
Это указатель на указатель на переменную неопределенного типа. Все указатели имеют одинаковый размер, поэтому void *
означает просто «указатель на что-то, но я понятия не имею, что это такое». void **
также может быть двумерным массивом неопределенного типа.
Переменная является указателем на что-то неопределенного типа (void). Оператор & возвращает адрес этой переменной, так что теперь у вас есть указатель на указатель на что-то. Поэтому указатель передается в функцию по ссылке. Функция может иметь побочный эффект, который изменит память, на которую ссылается этот указатель. Другими словами, вызов этой функции может изменить то, на что ссылается исходный указатель.
Разбирайте его по частям ...
myFunction принимает указатель на указатель типа void (что в значительной степени означает, что он может указывать на что угодно). Это можно было бы объявить примерно так:
myFunction(void **something);
Все, что вы передаете, должно иметь этот тип. Итак, вы берете адрес указателя и преобразуете его с помощью (void **), чтобы он стал пустым указателем. (По сути, лишая его всякого представления о том, на что он указывает - что в противном случае компилятор мог бы ныть.)
Это означает, что & переменная является адресом (& делает это) указателя, поэтому переменная является указателем. К чему? Кто знает!
Вот более полный фрагмент, чтобы дать представление о том, как это сочетается друг с другом:
#include <stdio.h>
int myInteger = 1;
int myOtherInt = 2;
int *myPointer = &myInteger;
myFunction(void **something){
*something = &myOtherInt;
}
main(){
printf("Address:%p Value:%d\n", myPointer, *myPointer);
myFunction((void**)&myPointer);
printf("Address:%p Value:%d\n", myPointer, *myPointer);
}
Если вы скомпилируете и запустите это, он должен дать следующий вид вывода:
Address:0x601020 Value:1
Address:0x601024 Value:2
Вы можете видеть, что myFunction изменила значение myPointer - что он мог сделать только потому, что ему был передан адрес указателя.