2009-05-10 4 views
2

Есть ли способ вернуть массив из функции? Более конкретно, я создал эту функцию:Как я могу вернуть массив?

char bin[8]; 

for(int i = 7; i >= 0; i--) 
{ 
    int ascii='a'; 
    if(2^i-ascii >= 0) 
    { 
     bin[i]='1'; 
     ascii=2^i-ascii; 
    } 
    else 
    { 
     bin[i]='0'; 
    } 
} 

и мне нужен способ, чтобы вернуть bin[].

ответ

3

Ваш массив является локальной переменной, выделенной в стеке. Вы должны использовать new [], чтобы выделить его в кучу. Тогда вы можете просто сказать: return bin;. Опасайтесь, что вам придется явно освободить его с помощью delete [], когда вы закончите с ним.

+2

Еще одна идея - использовать новый [] для создания массива и удаления [], чтобы удалить его. – 2009-05-10 18:45:10

+0

@Neil Butterworth - Как он отличается от того, что сказал Зифре? – Javier

+1

В C++ новые и удаленные отличаются от новых [] и delete [] – 2009-05-10 18:52:00

8

Вы не можете сделать это, но вы можете:

  • возвращающего dynamicaly выделяется массив - лучший принадлежащий смарт-указателем, так что вызывающий абонент не должен заботиться о освобождении памяти для него - вы можете также возвратите что-то вроде std :: vector таким образом.
  • заполнить массив/вектор, переданный вам в качестве аргумента указателем (предлагаемым) или неконстантной ссылкой.
+1

+1 голос, хороший ответ. Просто для того, чтобы прояснить ситуацию для Keand64, вы не можете вернуть бит, потому что выделенная ему память будет бесплатной после завершения функции, поэтому вам придется либо получить массив с памятью, выделенной в другом месте, либо использовать динамическую память, чтобы освободить его после прекращения его использования. – Javier

+0

Или используйте вектор. – 2009-05-10 18:48:32

+0

@Neil: у вас может получиться значительное повышение производительности во время копирования rvalue, если вы решите вернуть объект напрямую - теоретически хранение вектора может быть перенесено на копию rvalue вместо копирования, но я уверен, что это не то, что будет бывает. – RnR

2

Вы действительно задаете неправильный вопрос. Если вы хотите выполнить строчную обработку в C++, используйте классы std :: string и/или std :: vector, а не массивы char. Затем ваш код будет:

vector <char> func() { 
    vector <char> bin(8); 
    for(int i = 7; i >= 0; i--) { 
     int ascii='a'; 
     if (2^i - ascii >= 0) { 
      bin[i] = '1'; 
      ascii = 2^i - ascii; 
     } 
     else { 
     bin[i] ='0'; 
     } 
    } 
    return bin; 
} 
0

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

void FunctionAbc(char bin[], int size); 


void FuncationAbc(bin, size) 
{ 
for(int i = 7; i >= 0; i--) 
{ 
    int ascii='a'; 
    if(2^i-ascii >= 0) 
    { 
     bin[i]='1'; 
     ascii=2^i-ascii; 
    } 
    else 
    { 
     bin[i]='0'; 
    } 
} 

} 
1

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

void Calculate(std::vector<char>& bin) { 
    for(int i = 7; i >= 0; i--) 
    { 
    int ascii='a'; 
    if(2^i-ascii >= 0) 
    { 
     bin.push_back('1'); 
     ascii=2^i-ascii; 
    } 
    else 
    { 
     bin.push_back('0'); 
    } 
    } 
} 
0

Вы хотите передать по ссылке, следующим образом:

void modifyBin(char (&bin)[8]) 
{ 
    /* your function goes here and modifies bin */ 
} 

int main() 
{ 
    char bin[8]; 
    modifyBin(bin); 
    /* bin has been updated */ 
    return 0; 
} 
0

Я думаю, что все остальные ответили на этот один ... использовать контейнер вместо массива. Вот std::string версия:

std::string foo() { 
    int ascii = 'a'; 
    std::string result("00000000"); 
    for (int i=7; i>=0; --i) { 
     if (2^i-ascii >= 0) { 
      result[i] = '1'; 
      ascii = 2^i-ascii; 
     } 
    } 
    return result; 
} 

Я не совсем уверен, что если 2^i-ascii, хотите вы хотите или нет. Это будет проанализировано как (2^(i - ascii)), что немного странно.

1

Если вы хотите вернуть копию массива (может иметь смысл для небольших массивов), а массив имеет фиксированный размер, вы можете заключить его в структуру;

struct ArrayWrapper { 
    char _bin[8]; 
}; 

ArrayWrapper func() 
{ 
    ArrayWrapper x; 

    // Do your stuff here using x._bin instead of plain bin 

    return x; 
} 

Или просто используйте std :: vector, как уже было предложено.

1

Похожего реализованы в ответ @ АРИ, я хочу сказать, что уже есть решение подталкивания, boost::array решения вашей проблемы:

boost::array<char, 8> f() { 
    boost::array<char, 8> bin; 
    for(int i = 7; i >= 0; i--) { 
     int ascii = 'a'; 
     if(2^i-ascii >= 0) { 
      bin[i] = '1'; 
      ascii = 2^i-ascii; 
     } else { 
      bin[i] = '0'; 
     } 
    } 
} 

... 
boost::array<char, 8> a(f()); 

[Я не уверен, что вы хотите сделать с этим алгоритмом, хотя , но обратите внимание, что я думаю, что вы хотите сделать 1 << i (побитовое смещение) вместо 2^i который не экспоненцирование в C++.]

подталкивания массив нормальный массив, просто завернутые в структуры, так что вы не теряют производительности, что-то-никогда. Он также будет доступен в следующей версии C++ как std::array, и очень легко сделать сам, если вам не нужен begin()/size()/data() -сагар, который он добавляет (чтобы быть контейнером). Просто идти с самим основным:

template<typename T, size_t S> 
struct array { 
    T t[S]; 
    T& operator[](ptrdiff_t i) { return t[i]; } 
    T const& operator[](ptrdiff_t i) const { return t[i]; } 
}; 

Но, как обычно, использовать инструменты уже написанные другими людьми, в данном случае boost::array. Он также получил преимущество в том, совокупности (именно поэтому он не имеет пользовательскую объявленную конструкторы), так что это позволяет инициализировать с брекет приложенного списком:

boost::array<int, 4> a = {{ 1, 2, 3, 4 }}; 
Смежные вопросы