Найти размер массива без использования sizeof
Я искал способ найти размер массива в C без использования sizeof
, и я нашел следующий код:
int main ()
{
int arr[100];
printf ("%d\n", (&arr)[1] - arr);
return 0;
}
Может ли кто-нибудь объяснить мне, как это работает?
Ответы
Ответ 1
&arr
- это указатель на массив из 100 int
s.
[1]
означает "добавить размер объекта, на который указывает", который представляет собой массив из 100 int
s.
Таким образом, разница между (&arr)[1]
и arr
составляет 100 int
s.
(Обратите внимание, что этот трюк будет работать только в тех местах, где sizeof
все равно работал.)
Ответ 2
&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. Это не совсем понятно. См. Комментарии ниже, если они заинтересованы.
Ответ 3
Как правило, (согласно визуальной студии)
для массива &arr
совпадает с arr
, который возвращает начальный базовый адрес нашей функции.
(&arr)[0]
- это не что иное, как &arr
или arr
ex: он вернет некоторый адрес: 1638116
Теперь (&arr)[1]
означает, что мы начали доступ к массиву из bounce, означает следующий массив или следующий сегмент размера текущего массива (100 вперед).
ex: он вернет некоторый адрес: 1638216
Теперь, вычитая (&arr)[1] - (&arr)[0]=100
Ответ 4
&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;
}
Ответ 5
int arry [6] = {1,2,3,4,5,6}//позволяет элементам массива быть 6,
так...
размер в байтах = (char *) (arry + 6) - (char *) (arry) = 24;
Ответ 6
int main ()
{
int arr[100];
printf ("%d\n", ((char*)(&arr+1) - (char*)(&arr))/((char*) (arr+1) -(char*) (arr)));
return 0;
}