2010-03-17 6 views

ответ

9

Вы не можете. Указатель - это просто место в памяти и не содержит ничего особенного, которое могло бы определить размер.

Поскольку это C++, что вы можете сделать, это передать массив по ссылке, как так:

template <typename T, size_t N> 
void handle_array(T (&pX)[N]) 
{ 
    // the size is N 

    pX[0] = /* blah */; 
    // ... 
    pX[N - 1] = /* blah */; 
} 

// for a specific type: 
template <size_t N> 
void handle_array(int (const &pX)[N]) // const this time, for fun 
{ 
    // the size is N 

    int i = pX[0]; // etc 
} 

Но в противном случае вам нужно пройти начать & конца и сделать вычитание, как предполагает Alok, старт & размер, как вы предлагаете, или вырезать статический массив и использовать вектор, как предлагает Тайлер.

Если вы знаете размер массива вы будете работать, вы можете сделать typedef:

typedef int int_array[10]; 

void handle_ten_ints(int_array& pX) 
{ 
    // size must be 10 
} 

И только для размера:

template <typename T, size_t N> 
size_t countof(T (&pX)[N]) 
{ 
    return N; 
} 

template <typename T, size_t N> 
T* endof(T (&pX)[N]) 
{ 
    return &pX[0] + N; 
} 

// use 
int someArray[] = {1, 2, 6, 2, 8, 1, 3, 3, 7}; 

size_t count = countof(someArray); // 9 
std::for_each(someArray, endof(someArray), /* ... */); 

Я использую эти функции полезности время от времени.

+0

Вам лучше использовать 'typedef' для создания типа массива и принять ссылку на него, чтобы исключить« шаблон », если только эти методы не будут находиться в файле заголовка, и размер массива фактически меняется (но остается время деления на компиляцию). – Potatoswatter

+0

@Potatoswatter: Я не знаю, как сделать такой тип typedef. N не известен функции до тех пор, пока она не будет создана при вызове. Я добавлю пример typedef, это то, что вы имели в виду? – GManNickG

+0

Да, пример typedef, который вы добавили, - это то, что я имел в виду. 'template ' приятно с автоматическим размером 'int ary [] = {...};', но создание экземпляра может быть неудобным/запутанным, а преимущество мало AFAIK, если массив не объявлен таким образом. Или пользователь работает с несколькими фиксированными размерами. – Potatoswatter

15

Вы не можете этого сделать. Вам нужно передать длину массива вместе с указателем массива, или вам нужно использовать объект-контейнер, например std::vector.

+0

И вскоре std :: array :) – coelhudo

+2

На данный момент я ожидаю, что к моменту завершения C++ 4x будет собираться социальное обеспечение. –

+0

Я не понимаю, в чем дело: вы можете использовать boost :: array прямо сейчас. –

3

Вы имеете в виду что-то вроде:

int a[10]; 
int *start = a; 
int *end = a + 10; 
size_t n = end - start; /* pointers! :-) */ 
+2

Нет, указатель «конец» условно один-на-конец (что является законным), так что end-start = length, и поэтому вы можете делать такие вещи, как 'for (int * i = start; i! = end; ++ i)'. –

+0

@ Тайлер: спасибо. –

0

Вы не можете, если вы не знаете, что в разыменовывает конец указатель на. В случае массивов символов это '\ 0', поэтому вы можете зацикливаться до тех пор, пока не прочитаете этот символ, чтобы выяснить длину.

+1

В случае * строк * это обычно '\ 0'. Не каждый массив символов является строкой. – Potatoswatter

Смежные вопросы