C/C++

Что за число хранится в имени функции? (Си)

Сделал скрины с разных компиляторов на результат работы этого кода:
void func(){int a=5;}
int main(void)
{
int arr[ ]={1,2,3,4,5,6};
printf("%p\n%p\n", func, arr);
return 0;
}

Выводится на экран то, что находится в имени функции.
Ниже этого числа, которое находится в имени функции я вывел адрес массива.
Числа сильно различаются.
То что находится в имени массива и то что находится в имени функции имеет одну природу? Это шестнадцатеричные адреса?
Если это адреса, то почему с ними нельзя работать одинаково?
void func(){int a=5;}
int main(void)
{
int arr[]={1,2,3,4,5,6};
int *a=arr; //Так получается.
int *b=func; //Так не получается.
return 0;
}
Есть какой либо способ использовать этот адрес, который находится в имени функции?
Имя массива - указатель на первый его элемент.
Имя функции - указатель на расположение ее инструкций в памяти.

Оба указателя имеют размер sizeof(void *) и представляют из себя простые числа - адреса соответствующих байт в памяти.
Тип указателя показывает, как следует интерпретировать память, на которую он указывает. В самом указателе информация о его типе не лежит - указатель всего лишь хранит адрес 1 байта. Тип знает только компилятор.

Тип указателя можно привести к указателю любого другого типа. Так, например, можно интерпретировать 4 байта float как 4 байта int (если sizeof(int) = 4 байта, конечно). Вот так:

float a = 23.535;
int b = *(int *) &a;
Александр Мицай
Александр Мицай
3 568
Лучший ответ
Василий Сизов Указатель хранит в себе адрес первого байта массива. Ага)
Василий Сизов Оба указателя имеют размер sizeof(void *)???
---------------------------------
Как так если адрес массива запросто сохраняется в тип int* без всяких преобразований.
int arr[]={1,2,3,4,5,6};
int *a=arr;
Василий Сизов А, вы про размер писали. Там видимо что то другое имеется в виду.
Александр Мицай >Указатель хранит в себе адрес первого байта массива. Ага)

А что собственно не так? Все правильно.
Александр Мицай >Указатель хранит в себе адрес первого байта массива. Ага)

Только вот я так не писал. Указатель хранит в себе адрес первого байта какого бы то ни было типа, на который он указывает
Василий Сизов То что sizeof(имя массива) выдаёт размер всего массива я например не вижу ничего странного.
Вот подобный пример scanf("%d", &a); Здесь записывается значение по адресу, а в sizeof(имя массива) читается размер по адресу.
Василий Сизов Всё так. Я пишу, тренируюсь, вспоминаюи запоминаю)
Василий Сизов Было бы немного дольше, но я бы справился. Книгу видимо надо будет прочитать. Но как то скучно. По одной теме сейчас я больше читаю и смотрю чем написано в книге.
Я могу точно сказать что вы сильно преувеличиваете влияние ответов. Очень помогает конечно, но я вижу это на практике в среде разработки, для уточнения спрашиваю.
Это не первая большая область, которую учу без посторонней помощи, поэтому знаю о чём говорю.
Василий Сизов Мозг научился сам находить ответы, тем более часто бесполезно спрашивать. И большинство ответов я решаю сам сейчас. Я ведь не спрашиваю какой тип имеют переменные и прочую элементарщину или на какую кнопку нажать чтоб запустить Дебаггинг.
Василий Сизов Вот вы сказали про адрес первого байта хранящийся в указателе. С чего то вы решили что я этого не знал. А я на этом много примеров построить могу.
Василий Сизов Вот например так изменили адрес первого байта массива
int main(void)
{
int arr[]={1,2,3,4,5,6};
int *a = &arr[1];
printf("%d\n", a[0]);
return 0;
}
Теперь массив А [] начинается с другого места.
Василий Сизов Кроме того что это знать, это надо ещё осознать и мочь применить, а это никто посторонний сделать за меня не сможет.
Василий Сизов Я раньше тоже замечал что указатели ведут себя по другому в sizeof()
Что то в этом есть.
Василий Сизов Адреса одинаковые, но результат sizeof() разный.
int main(void)
{
int arr[]={1,2,3,4,5,6};
float a = 5444444.555555556f;
printf("%p\n%p\n", arr, &arr);
printf("%lld\n%lld\n", sizeof(arr), sizeof(&arr));
return 0;
}
Василий Сизов int main(void)
{
int arr[]={1,2,3,4,5,6};
printf("%p\n%p\n", arr, &arr);
printf("%lld\n%lld\n", sizeof(arr), sizeof(&arr));
return 0;
}
Василий Сизов Значит отличие этого &arr от этого arr в том что это arr имеет тип массива, а это &arr не имеет тип массива. ок
Василий Сизов Сейчас больше понятно, помню я парился над этой темой тоже. Не понимал почему по разному работает указатель в sizeof() и имя массива, хотя оба содержат адрес.
Василий Сизов sizeof() возвращает число 8 если в это sizeof() поместить указатель Что это за цифра?
Василий Сизов Размер самого указателя? 8 Байт?
Василий Сизов Да, нашёл:
Размер указателя зависит от разрядности вашего приложения:
на 32-битной версии - 4 байта
на 64-битной версии - 8 байт
> Выводится на экран то, что находится в имени функции
бред
это адрес начала функции, ни про какое имя функции речь не идёт
> То что находится в имени массива и то что находится в имени функции имеет одну природу?
да, это адреса массива и функции соотвественно в памяти
про имя массива тоже бред, кстати
> Это шестнадцатеричные адреса?
да
> Если это адреса, то почему с ними нельзя работать одинаково?
потому что указатели имеют разные типы
тем не менее, можно без проблем скастовать один к другому явно, и всё сработает
правда, зачем...
int *b=(int*)&func; //Так получается.
к слову, свежий гцц и с неявным кастом всё компилит, только предупреждение выводит
Давид Атаян Стоит добавить, что можно создать указатель на функцию.
https://en.cppreference.com/w/cpp/language/pointer#Pointers_to_functions
https://en.cppreference.com/w/cpp/utility/functional/function
Василий Сизов Указатели имеют разные типы?
В типе int* сохраняется шестнадцатеричный адрес массива.
Почему шестнадцатеричный адрес функции не может сохраниться в этом же типе int*?

Про начальный бит адреса массива я знаю, так выражаюсь просто неправильно)
Василий Сизов Указатель на функцию называется. Ок. Посмотрю ещё по теме.
Василий Сизов Ааа, функция то имеет тип void, понял.
Я учусь. Просто ради интереса. Для понимания работы кода.
Имея адрес функции ты можешь её вызвать. Даже из dll. Есть хорошая библиотека libffi её использует Python, Ruby и др., чтобы вызывать функции на Си, имея её адрес