Подтвердить что ты не робот

Разница между двойным указателем и массивом указателей

В обычной программе c/С++ мы пишем основную функцию как

int main(int c, char **argv)

или

int main(int c, char *argv[])

Здесь argv представляет массив указателей, но мы даже представляем двойной указатель (указатель на указатель) с помощью **.

ex:

char p,*q,**r;
q=&p;
r=&q;

Здесь r - двойной указатель, а не массив указателей.

Может ли кто-нибудь объяснить разницу?

4b9b3361

Ответ 1

При использовании в качестве параметра функции

char a[]  // compiler interpret it as pointer to char

эквивалентно

char *a

и аналогично, в подписи main, char *argv[] эквивалентно char **argv. Обратите внимание, что в обоих случаях char *argv[] и char **argv, argv имеет тип char ** (а не массив указателей!).

То же самое не относится к объявлению

char **r;
char *a[10];

В этом случае r имеет указатель типа на указатель на char, а a - массив типов указателей на char.
Назначение

r = a;   // equivalent to r = &a[0] => r = &*(a + 0) => r = a

действителен, так как в этом выражении снова тип массива a будет преобразован в указатель на его первый элемент и, следовательно, типа char **.

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

Рекомендуемое чтение:

Ответ 2

argv - это аргумент, поэтому массив разлагается на указатель, и нет никакого различия, кроме размера (int c).

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

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

Немного связанный вопрос: выражение extern, T * v/s T []

Ответ 3

Смотри! Двойные указатели на самом деле хранят вот так
Скажем

int p,*q,**r; 
p=50;

пусть адрес p равен 400 (&p is 400) если мы пишем q=p и печатаем q, мы получим 400 как ответ, так как q ссылается на адрес p и *p будет выводить 50 как вывод, так как operator * ссылается на "значение по адресу". Теперь, скажем, q имеет адрес 500 (&q выводит 500), поэтому, когда мы делаем это так: r=q r содержит значение 500 и при префиксе r с *, то есть *r вывод должен быть 400, потому что r отображает значение q, в котором хранится адрес p является переменной указателя.

Таким образом,
если в программе C мы запускаем следующий код

int main()
{
   int p,*q,**r; //assume the address of p to be 400
                 //assume the address of q to be 500
   p=50;
   q=p;
   r=q;

printf("Value of p-->%d",p);
printf("\nValue of q-->%d",q);
printf("\nValue at address of q \"in the address displayed above\"-->%d",*p);
printf("\nValue of r \"which will be the address of q\"-->%d",r);
printf("\nValue of r \"which will be the adddress of p-->%d",*r);
printf("\nValue of r \"which will be the value of p\"-->%d",**r);
/*
Please change the format specifiers and replace the specifier from %d to %u in case the address value is not being displayed
*/
return 0;
}

ВЫВОД
-------
Значение p → 50
Значение q → 400
Значение по адресу q "в указанном выше адресе" → 50
Значение of r "который будет адресом q" → 500
Значение r ", которое будет adddress of p" → 400
Значение r ", которое будет значением p" → 50

В приведенном выше примере я просто попытался объяснить использование двойного указателя. Возможно, вы можете это знать. Я все же понял

Теперь используем приведенный выше пример с массивом.
Посмотрите
Массивы уже указатели, так как они могут быть увязками, указанными как * (a + 1) или [1].
Таким образом, двойные указатели могут означать массив указателей или массив Array в соответствии с вашим вопросом. Использование обозначений с двойными указателями зависит от ситуации.
В вопросе, который вы разместили выше, _TCHAR ** argv или просто char ** argv - это массив символов для ввода в консоль, который всегда принимается как поток символов.
В java мы используем нечто похожее, например public static void main (String argv [])
Это наглядно показывает, что основной метод принимает входные данные, которые являются массивом char массивов (или Строки должны быть немного полными).
Надеюсь, вы поняли разницу. Если не любезно прокомментировать. Я объясню вам это.
Спасибо