Как я могу вернуть массив? - PullRequest
2 голосов
/ 10 мая 2009

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

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[].

Ответы [ 9 ]

8 голосов
/ 10 мая 2009

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

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

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

2 голосов
/ 10 мая 2009

Вы действительно задаете не тот вопрос. Если вы хотите выполнять обработку строк в 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;
}
1 голос
/ 10 мая 2009

Аналогично реализации ответа @ ari, я хочу сказать, что решение для повышения уже существует, 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 ++.]

Boost-массив - это обычный массив, просто обернутый в структуру, так что вы не теряете производительности вообще. Он также будет доступен в следующей версии 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 }};
1 голос
/ 10 мая 2009

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

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 голос
/ 10 мая 2009

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

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 голосов
/ 10 мая 2009

Я думаю, что все остальные ответили на этот ... использовать контейнер вместо массива. Вот версия 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)), что немного странно.

0 голосов
/ 10 мая 2009

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

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 голосов
/ 10 мая 2009

вам нужно передать массив 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';
    }
}

}
...