Почему функция sizeof не работает здесь так, как должна [дубликат]

Вопрос или проблема

Почему функция sizeof не работает здесь так, как должна [дубликат]

Я просто играл с кодом, и вдруг заметил, что после передачи массива по ссылке sizeof(arr)/sizeof(arr[0]) дает другой результат, чем я ожидал. Если я передаю только ссылку, то len=1 может быть оправданным, так как sizeof(arr[0])/sizeof(arr[0]). Что не так с этим? Какое понятие у меня упущено?

#include<iostream>
using namespace std;

void display(int *arr)
{
    int len=sizeof(arr)/sizeof(arr[0]);
    cout<<len<<"\n";
    for(int i=0;i<50;++i)
    {
        cout<<arr[i];
    }
    cout<<"\n";
}

int main()
{
    int arr[50]={0};
    for(int i=0;i<50;++i)
    {
        arr[i]=i;
    }
    display(arr);
    return 0;
}

Почему длина вывода не 50, как должно быть? Почему она равна только 2 вместо 50?

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

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

Ответ или решение

Вопрос, который вы поднимаете, касается значения функции sizeof при передаче массива в функцию. Давайте разберёмся, почему функция sizeof не работает так, как вы ожидаете.

Когда вы передаёте массив в функцию, он автоматически преобразуется в указатель на первый элемент массива. В вашем случае, когда вы определяете функцию display, параметр int *arr фактически является указателем, а не массивом. Это приводит к тому, что расчет sizeof(arr) возвращает размер указателя, а не размер всего массива.

Почему sizeof возвращает 2

int len = sizeof(arr) / sizeof(arr[0]);

Здесь sizeof(arr) возвращает размер указателя (например, 4 или 8 байт в зависимости от компилятора и архитектуры), а sizeof(arr[0]) возвращает размер одного элемента массива (в данном случае 4 байта для типа int). Поэтому результат деления возвращает число, меньшее 50, вероятно, 1 или 2, что не соответствует размеру массива, который вы передали.

Как правильно узнать размер массива

Чтобы корректно получить размер массива, вы можете передать его размер в функцию как дополнительный параметр. Это также может выглядеть следующим образом:

void display(int *arr, int size)
{
    cout << size << "\n";  // Теперь здесь будет выводиться 50
    for(int i = 0; i < size; ++i)
    {
        cout << arr[i];
    }
    cout << "\n";
}

И в main:

display(arr, sizeof(arr) / sizeof(arr[0]));  // Передаётся размер массива

Заключение

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

Это объясняет, почему вы получаете неожиданное количество элементов при использовании sizeof, как в вашем примере.

Оцените материал
Добавить комментарий

Капча загружается...