Размер массива С++

Возможный дубликат:
Размер массива, переданный как параметр

Мне было интересно, почему вывод следующего кода равен 1 и 9. Это из-за необъявленного массива в размере функции? Как я могу отделить "размер массива" к функции?

#include "stdafx.h"
#include <iostream>
using namespace std;

int size(int a[])
{
    return sizeof a/sizeof a[0];
}

int main()
{   
    int a[] = {5,2,4,7,1,8,9,10,6};
    cout << size(a) << endl;
    cout << sizeof a/sizeof a[0] << endl;
    system("pause");
    return 0;
}

Ответ 1

Когда вы пишете size(a), вы передаете указатель, а не массив. Поскольку размер указателя и int равен 4 или 8 (в зависимости от ABI), вы получаете sizeof(int *)/sizeof int ( 4/4 = 1 для 32-разрядных машин и 8/4 = 2 для 64-битных), 1 или 2.

В С++ при передаче массива в качестве аргумента функции фактически передается указатель на массив.

Ответ 2

Ответ Maroun85 правильный. Это не очевидно, но a в int size(int a[]) является указателем.

Но почему бы вам не сделать это С++. Используя std::vector s

std::vector<int> a = {5,2,4,7,1,8,9,10,6};
cout << a.size() << endl;

здесь нет трюков

- отредактировать

Если ваш компилятор не поддерживает С++ 11. Вы можете сделать:

std::vector<int> a;
a.push(5);
a.push(2);
...
cout << a.size() << endl;

Ответ 3

Ваша функция size() не может работать так, как вы хотите, потому что, когда вы передаете массив функции, массив распадается на указатель на свой первый элемент. Ваши распады a для оператора int* и sizeof на указателе возвращают размер указателя, а не массив. Рассмотрите возможность использования std::vector<int>, так как это позволит вам получать размер вектора каждый раз, когда вы передаете его функции.

Ответ 4

При передаче массивов в функции они распадаются на указатели. Итак, ваша функция size() эквивалентна:

int size(int* a)
{
    return sizeof a/sizeof a[0];
}

И sizeof a - это размер указателя, который является таким же, как размер int здесь, следовательно, выход.

Ответ 5

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

Таким образом, в функции a есть указатель на int, и (для 32-битных интерлееров) размер указателя на int совпадает с размером int.

Ответ 6

sizeof оценивается во время компиляции, а не во время выполнения. Компилятор не анализирует, что вы передаете функции size, а скорее рассматривает параметр функции как указатель. Таким образом, в вашей функции size результатом sizeof a является размер указателя на int, который, случайно, равен размеру int в вашей системе.

Ответ 7

Лучшее объяснение, почему ваше решение не работает, - это ответ Маруна.

О второй части вопроса ( "как это можно сделать?" ), вы можете сделать это с помощью функции шаблона:

template <typename T, size_t n> const size_t size(const T (&)[n]) { return n; }

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

Если вам нужно это для работы с массивами, которые не являются константами времени компиляции (например, что-то, что вы выделяете с помощью operator new[] или с использованием нестандартного расширения компилятора), вам нужно явно хранить размер где-то.

(Кстати, мой вышеприведенный вывод технически неверен, действительно, размер распределения обычно сохраняется, но это детали реализации, от которых вы не можете и не должны зависеть.)