Я искал способ найти размер массива в C без использования sizeof, и я нашел следующий код:
int main ()
{
int arr[100];
printf ("%d\n", (&arr)[1] - arr);
return 0;
}
Может ли кто-нибудь объяснить мне, как это работает?
Я искал способ найти размер массива в C без использования sizeof, и я нашел следующий код:
int main ()
{
int arr[100];
printf ("%d\n", (&arr)[1] - arr);
return 0;
}
Может ли кто-нибудь объяснить мне, как это работает?
&arr - это указатель на массив из 100 int s.
[1] означает "добавить размер объекта, на который указывает", который представляет собой массив из 100 int s.
Таким образом, разница между (&arr)[1] и arr составляет 100 int s.
(Обратите внимание, что этот трюк будет работать только в тех местах, где sizeof все равно работал.)
&arr дает вам указатель на массив. (&arr)[1] эквивалентно *(&arr + 1). &arr + 1 дает указатель на массив из 100 int, который следует за arr. Разделение его на * дает вам следующий массив. Поскольку этот массив используется в аддитивном выражении (-), он распадается на указатель на его первый элемент. То же самое происходит с arr в выражении. Таким образом, вы вычитаете указатели, один указывает на несуществующий элемент сразу после arr, а другой указывает на первый элемент arr. Это дает вам 100.
Но он не работает. %d используется для int. Разница указателей возвращает вас ptrdiff_t, а не int. Вы должны использовать %td для ptrdiff_t. Если вы относитесь к printf() о типах параметров, которые вы передаете, вы получаете заслуженное поведение undefined.
EDIT: (&arr)[1] может вызвать поведение undefined. Это не совсем понятно. См. Комментарии ниже, если они заинтересованы.
Как правило, (согласно визуальной студии)
для массива &arr совпадает с arr, который возвращает начальный базовый адрес нашей функции.
(&arr)[0] - это не что иное, как &arr или arr
ex: он вернет некоторый адрес: 1638116
Теперь (&arr)[1] означает, что мы начали доступ к массиву из bounce, означает следующий массив или следующий сегмент размера текущего массива (100 вперед).
ex: он вернет некоторый адрес: 1638216
Теперь, вычитая (&arr)[1] - (&arr)[0]=100
&variable указывает местоположение переменной (назовите ее как P) &variable + 1 указывает адрес места рядом с переменной. (назовите его N)
(char*)N-(char*)P показывает количество символов между N и P. Поскольку каждый символ имеет размер 1 байт, поэтому приведенный выше результат дает количество байтов P и N. (что равно размеру массива в байтах).
Аналогично,
(char*) (a+1)-(char*)a; дает размер каждого элемента массива в байтах.
Итак, количество элементов в массиве = (size of array in bytes)/(size of each element in the array in bytes)
#include<stdio.h>
int main()
{
int a[100];
int b = ((char*)(&a+1)-(char*)(&a));
int c = (char*) (a+1)-(char*)a;
b = b/c;
printf("The size of array should be %d",b);
return 0;
}
int arry [6] = {1,2,3,4,5,6}//позволяет элементам массива быть 6, так... размер в байтах = (char *) (arry + 6) - (char *) (arry) = 24;
int main ()
{
int arr[100];
printf ("%d\n", ((char*)(&arr+1) - (char*)(&arr))/((char*) (arr+1) -(char*) (arr)));
return 0;
}