Почему размер массива не такой же, как и у основного?

Почему размер массива, отправленного как параметр, не совпадает с основным?

#include <stdio.h>

void PrintSize(int p_someArray[10]);

int main () {
    int myArray[10];
    printf("%d\n", sizeof(myArray)); /* As expected, 40 */
    PrintSize(myArray);/* Prints 4, not 40 */
}

void PrintSize(int p_someArray[10]){
    printf("%d\n", sizeof(p_someArray));
}

Ответы

Ответ 1

Нет, тип массива неявно преобразуется в тип указателя, когда вы передаете его функции.

Итак,

void PrintSize(int p_someArray[10]) {
    printf("%zu\n", sizeof(p_someArray));
}

и

void PrintSize(int *p_someArray) {
    printf("%zu\n", sizeof(p_someArray));
}

эквивалентны. Итак, вы получаете значение sizeof(int*)

Ответ 2

Это указатель, поэтому для его общей реализации передать размер массива в качестве второго параметра функции

Ответ 3

Как утверждали другие, массивы распадаются на указатели на их первый элемент при использовании в качестве параметров функции. Также стоит отметить, что sizeof не оценивает выражение и не требует скобок при использовании с выражением, поэтому ваш параметр фактически не используется вообще, поэтому вы можете также написать sizeof с типом, а не с значением.

#include <stdio.h>

void PrintSize1 ( int someArray[][10] );
void PrintSize2 ( int someArray[10] );

int main ()
{
    int myArray[10];
    printf ( "%d\n", sizeof myArray ); /* as expected 40 */
    printf ( "%d\n", sizeof ( int[10] ) ); /* requires parens */
    PrintSize1 ( 0 ); /* prints 40, does not evaluate 0[0] */
    PrintSize2 ( 0 ); /* prints 40, someArray unused */
}

void PrintSize1 ( int someArray[][10] )
{
    printf ( "%d\n", sizeof someArray[0] );
}

void PrintSize2 ( int someArray[10] )
{
    printf ( "%d\n", sizeof ( int[10] ) );
}

Ответ 4

Итак, вам нужно будет передать длину массива в качестве второго параметра. Когда вы пишете код, в котором вы объявляете массив постоянного размера, а затем передаете этот массив функции, больно, чтобы константа длины массива отображалась в нескольких местах вашего кода...

K & R для спасения:

#define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0])) 

Итак, теперь вы можете сделать, например:

int a[10];
...
myfunction(a, N_ELEMENTS(a));

Ответ 5

Поскольку массивы распадаются на указатели, когда они передаются как параметры. Вот как работает C, хотя вы можете передавать "массивы" на С++ по ссылке и преодолевать эту проблему. Обратите внимание, что вы можете передавать массивы разных размеров этой функции:

 // 10 is superfluous here! You can pass an array of different size!
void PrintSize(int p_someArray[10]);

Ответ 6

В С++ вы можете передать массив по ссылке для этой цели:

void foo(int (&array)[10])
{
    std::cout << sizeof(array) << "\n";
}

Ответ 7

Поведение, которое вы обнаружили, на самом деле является большой бородавкой на языке C. Всякий раз, когда вы объявляете функцию, которая принимает параметр массива, компилятор игнорирует вас и изменяет параметр на указатель. Таким образом, эти объявления ведут себя как первый:

void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)

a будет указателем на int во всех четырех случаях. Если вы передадите массив в func, он немедленно распадается на указатель на его первый элемент. (В 64-разрядной системе 64-разрядный указатель в два раза больше, чем 32-битный int, поэтому коэффициент sizeof возвращает 2.)

Единственная цель этого правила - поддерживать обратную совместимость с историческими компиляторами, которые не поддерживают передачу агрегированных значений в качестве аргументов функции.

Это не означает, что невозможно передать массив функции. Вы можете обойти эту бородавку, вставив массив в структуру (это в основном цель С++ 11s std:: array):

struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0]));  /* prints 5 */
}

или передав указатель на массив:

void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0]));  /* prints 5 */
}

Если размер массива не является константой времени компиляции, вы можете использовать метод указатель-массив с массивами переменной длины C99:

void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0]));  /* prints n */
}

Ответ 8

На языке C нет способа определить размер неизвестного массива, поэтому количество должно передается, а также указатель на первый элемент.

Ответ 9

Вы не можете передавать массивы в функции.

Если вы действительно хотите напечатать размер, вы можете передать указатель на массив, но он не будет вообще вообще, поскольку вам нужно также определить размер массива для этой функции.

#include <stdio.h>

void PrintSize(int (*p_anArray)[10]);

int main(void) {
    int myArray[10];
    printf("%d\n", sizeof(myArray)); /* as expected 40 */
    PrintSize(&myArray);/* prints 40 */
}

void PrintSize(int (*p_anArray)[10]){
    printf("%d\n", (int) sizeof(*p_anArray));
}

Ответ 10

Поведение по дизайну.

Такой же синтаксис в объявлении параметра функции означает совершенно иное, чем определение локальной переменной.

Причина описана в других ответах.

Ответ 11

В языке C, когда вы передаете массив в качестве аргумента функции, он автоматически преобразуется в указатель, массив переходит из одной функции, другая функция известна как вызов по ссылке. Именно по этой причине вызываемая функция получает только указатель, указывающий на первый элемент функции. Это причина

fun (int a []) аналогично fun (int * a);

поэтому, когда вы печатаете размер массива, он будет печатать размер первого элемента.

Ответ 12

В программировании 'C' languange 'sizeof()' является оператором, и он возвращает размер объекта в байтах. Параметр оператора sizeof() должен быть левым типом (integer, float number, struct, array). Так что если вы хотите знать размер массива в байтах, вы можете сделать это очень просто. Просто используйте оператор sizeof(), и для его аргумента используйте имя массива. Например:

#include <stdio.h>

main(){

 int n[10];
 printf("Size of n is: %d \n", sizeof(n)); 

}

Вывод на 32-битной системе будет: Размер n равен: 40.Because ineteger на 32-й системе - 4 байта. В 64x это 8bytes. В этом случае у нас есть 10 целых чисел, объявленных в одном массиве. Таким образом, результат равен '10 * sizeof (int) '.

Некоторые советы:

Если у нас есть массив, объявленный как этот 'int n [] = {1, 2, 3,... 155..};'. Поэтому мы хотим знать, сколько элементов хранится в этом массиве. Используйте этот альгорифм:

sizeof (name_of_the_array)/sizeof (array_type)

Код: #include

Основной() {

int n[] = { 1, 2, 3, 44, 6, 7 };
printf("Number of elements: %d \n", sizeof(n) / sizeof(int));
return 0;

}

Ответ 13

Массивы имеют только размерность. По большей части массив является указателем на память. Размер в объявлении сообщает компилятору, сколько памяти выделяется для массива - оно не связано с типом, поэтому sizeof() не имеет ничего общего.