Сделал скрины с разных компиляторов на результат работы этого кода:
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;
> Выводится на экран то, что находится в имени функции
бред
это адрес начала функции, ни про какое имя функции речь не идёт
> То что находится в имени массива и то что находится в имени функции имеет одну природу?
да, это адреса массива и функции соотвественно в памяти
про имя массива тоже бред, кстати
> Это шестнадцатеричные адреса?
да
> Если это адреса, то почему с ними нельзя работать одинаково?
потому что указатели имеют разные типы
тем не менее, можно без проблем скастовать один к другому явно, и всё сработает
правда, зачем...
int *b=(int*)&func; //Так получается.
к слову, свежий гцц и с неявным кастом всё компилит, только предупреждение выводит
Имея адрес функции ты можешь её вызвать. Даже из dll. Есть хорошая библиотека libffi её использует Python, Ruby и др., чтобы вызывать функции на Си, имея её адрес
---------------------------------
Как так если адрес массива запросто сохраняется в тип int* без всяких преобразований.
int arr[]={1,2,3,4,5,6};
int *a=arr;
А что собственно не так? Все правильно.
Только вот я так не писал. Указатель хранит в себе адрес первого байта какого бы то ни было типа, на который он указывает
Вот подобный пример 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;
}
Теперь массив А [] начинается с другого места.
Что то в этом есть.
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 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;
}
Размер указателя зависит от разрядности вашего приложения:
на 32-битной версии - 4 байта
на 64-битной версии - 8 байт