В C невозможно узнать длину массива по своей сути.Это связано с тем, что массив на самом деле представляет собой просто непрерывный кусок памяти, а значение, переданное функциям, на самом деле является просто указателем на первый элемент в массиве.В результате этого, чтобы на самом деле узнать длину массива внутри функции, отличной от функции, в которой был объявлен этот массив, вы должны каким-то образом передать это значение функции.Два распространенных подхода - это использование значений часовых, которые указывают на последний элемент (аналогично тому, как NULL используется в качестве последнего символа строки в C), или предоставление другого параметра, который содержит длину массива.
Asочень распространенный пример этого: если вы написали какие-либо программы, использующие параметры командной строки, то вы наверняка знакомы с общим определением int main(int argc, char *argv[])
, которое использует второй из вышеупомянутых подходов, предоставляя длину argv
массив через параметр argc
.
У компилятора есть несколько способов обойти это для локальных переменных.Например, будет работать следующее:
#include <stdio.h>
int main(){
int nums[10] = {0};
printf("%zu\n", sizeof(nums)/sizeof(nums[0]));
return 0;
}
Который печатает 10
в STDOUT;однако это работает только потому, что операция sizeof
выполняется локально, и компилятор знает длину массива в этой точке.
С другой стороны, мы можем рассмотреть ситуацию передачи массива другомуфункция:
#include <stdio.h>
int tryToGetSizeOf(int arr[]){
printf("%zu", sizeof(arr)/sizeof(arr[0]));
}
int main(){
int nums[10] = {0};
printf("%zu\n", sizeof(nums)/sizeof(nums[0]));
puts("Calling other function...");
tryToGetSizeOf(nums);
return 0;
}
Это приведет к выводу на STDOUT следующего:
10
Calling other function...
2
Это может быть не то значение, которое вы ожидаете, но это происходит из-за того, чтосигнатура метода int tryToGetSizeOf(int arr[])
функционально эквивалентна int tryToGetSizeOf(int *arr)
.Следовательно, вы делите размер целочисленного указателя (int *
) на размер одного int
;в то время как вы все еще находитесь в локальном контексте main()
(, т.е., где массив был определен изначально ), вы делите размер выделенной области памяти на размер типа данных этой области памятиразделен как (int
).
Пример этого доступен на Ideone .