Размер массива Переполнение стека

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

Мне было интересно, почему вывод следующего кода 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;
}

10

Решение

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

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

12

Другие решения

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

Но почему бы вам не сделать это способом C ++. С помощью std::vectors

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

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

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

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

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

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

5

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

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

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

4

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

3

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

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

3

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

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

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

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

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

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

3
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector