Добрый день господа, собственно вопрос. Вижу периодически, что в некоторых функциях указатели вставляют то таким образом: function(&name), то таким: function(name)
Может кто нибудь объяснить, что да как с этим делом? Я понимаю, как работают указатели, но чёт догнать не могу, почему в функции стоит входной параметр char, а отправляют получается адрес указателя. И если можно, пример для использования возможных вариантов. Заранее спасибо!
Ответ
В выражениях массивы за редким исключением неявно преобразуются в указатель на свой первый элемент. Поэтому когда вы передаете массив в функцию, как в нижеприведенном примере
void f( int *a, size_t n )
{
for ( size_t i = 0; i < n; i++ ) printf( "%d ", a[i] );
printf( "
" );
}
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
f( a, 10 );
то не надо указывать перед именем массива оператор &. Массив уже преобразован в указатель типа int *
Однако если вы имеете дело со скалярными объектами, как, например, выражение a[0], которое представляет собой первый элемент массива, то есть скалярный объект со значением 0, как следует из определения массива в примере выше, то если вы хотите передать его адрес в вышеуказанную функцию , то вам надо будет записать
f( &a[0], 10 );
Фактически, данные два вызова
f( a, 10 );
и
f( &a[0], 10 );
эквивалентны, так как в обоих случаях передается адрес на первый элемент массива.
В виду этого данные объявления функции эквивалентны и объявляют одну и ту же функцию
void f( int a[10], size_t n )
void f( int a[20], size_t n )
void f( int a[], size_t n )
void f( int *a, size_t n )
Вы все эти объявления можете одновременно включить в программу, и программа будет успешно компилироваться.
То же самое справедливо и для символьных массивов. Имейте в виду, что строковые литералы также имеют тип массивов. И если имеется вызов вида
h( "Hello" );
где h - это некоторая функция, то в функцию передается адрес первого символа литерала, так как, как описано выше, данный литерал, который представляет из себя символьный массив, неявно преобразуется в указатель на свой первый символ.
В заключение приведу демонстрационную программу, в которую также включен пример, показывающий, что строковые литералы - это массивы.
#include
void f( int a[10], size_t n );
void f( int a[20], size_t n );
void f( int a[], size_t n );
void f( int *a, size_t n );
void f( int *a, size_t n )
{
for ( size_t i = 0; i < n; i++ ) printf( "%d ", a[i] );
printf( "
" );
}
void h( char c ) { printf( "%c
", c ); }
int main(void)
{
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
f( a, 10 );
f( &a[0], 10 );
h( "Hello"[0] );
return 0;
}
Вывод программы на консоль
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
H