2012-07-04 4 views
1

У меня есть функция, и я хочу, чтобы вернуть массив междунар, но я не хочу, чтобы создать переменную только для этого, что, как этоВозвращение массива на лету (C)

int* foo() 
{ 
     static int bar[]={1,2,3}; // edit thanks to comments 
     return bar; 
} 

Чтобы обойти это, я попытался это:

 return (Uint8Type*) gAppCanContext.BluetoothMacAddr[0] + MacAddr[1] + '-'\ 
       + gAppCanContext.BluetoothMacAddr[2] + MacAddr[3] + '-' ; 

Но это не работает. Я также пробовал:

return (Uint8Type*[]){ MacAddr[0] , MacAddr[1] + '-' MacAddr[3] ... }; 

Он компилируется с предупреждением, и если я выполняю программу, он замерзает. Я тоже пытался играть со звездочками и амперсандами, но я не мог заставить его работать правильно.

Возможно ли это? Если да, то как?

Добавлено: I can not use malloc - это встроенная система без динамического распределения.

+6

Ваш 'функция Foo' фактически не работает. Помимо хранения строк в 'int []', использование возвращаемого значения вызывает неопределенное поведение. Используйте 'malloc'. –

+0

Вы не можете конкатенировать строки таким образом в C. Строки - это просто указатели - добавление изменяет смещение указателя, а не добавляя символы. –

+0

Итак, не обращая внимания на проблемы с вашим кодом, почему ненависть к переменным? –

ответ

3

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

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

Возможно ли это? Если да, то как?

  • Вы можете malloc некоторую память и возвращает указатель на него
  • Вы можете использовать static объект, как уже упоминалось, Electro.
+0

Или массив 'static'. – Electro

0

, если данные в обув не является динамическим, вы можете попробовать это:

const char *foo(void) 
{ 
    static const char *bar[] = {"aa", "bb", "cc"}; 
    return bar; 
} 

с помощью «статические», данные не будут исчезать, когда он выходит из области видимости.

+0

Возможно, вы захотите добавить тип в 'bar'. – unwind

+1

также, повторная активизация является большой проблемой – unkulunkulu

+1

Обратите внимание, что это очень плохая практика. Это не объектно-ориентированный дизайн, он также не является потокобезопасным. – Lundin

0
int* foo() 
{ 
    int bar[]={"aa","bb","cc"}; 
    return bar; 
} 

No can can. C на самом деле не имеет «массивов»; когда вы возвращаете бар, он действительно просто вернет указатель на первый элемент панели, который будет удален к тому моменту, когда вы вернетесь в вызывающий.

Кроме того, вы можете решить, хотите ли вы «строки» или РАСЧ в массиве :-)

Вы можете вставить массив в структуры

struct Weird 
{ 
    int bar[3]; 
} 

и вернуться, что:

struct Weird foo(void) 
{ 
    struct Weird bar; 
    bar.bar[0]=1; 
    bar.bar[1]=5; 
    bar.bar[2]=10; 
    return bar; 
} 

Тем не менее, я не уверен, что это то, что вы хотите.Я думаю, что вы действительно хотите, чтобы ознакомиться с C :-)

Вы также можете получить свой первый пример, чтобы работать, если вы

int* foo() 
{ 
    static int bar[]={1,2,3}; 
    return bar; 
} 

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

+0

Я хочу поправиться, я могу сделать простой путь или найти короткий путь. – Thomas

+1

C имеет массивы –

0

Если стандарт не изменился, C возвращает значения, которые могут быть возвращены в регистр. Таким образом, в вашем случае ваша функция вернет указатель на строку символов.

Как вы создаете эту строку символов, вы должны учитывать лучшие практики.

Вы можете объявить статический массив в функцию и возвращает указатель на него:

char * cp1() 
{ 
    static char szForeverBuf[100] = {0}; 

    return (char *) &szForeverBuf; 
} 

Это может быть хорошо способ обращаться с вещами, если cp1 вызывается один раз при запуске, но вызывается более одного раза может и, вероятно, приведет к ошибкам, поскольку функция возвращает только адрес буфера, созданного во время компиляции.

Иными словами, функция cp1 возвращает указатель на символ, значение которого никогда не изменяется, каждый раз, когда вызывается cp1. Следовательно, поэтому функция может быть полезна при запуске.

Вы также можете создать динамическую память, как это:

#include <stdio.h> 
#include <stdlib.h> 

char * cp2(int nSizeP) 
{ 
    char *pszForeverBuf = NULL; 
    int nSize = 0; 

    if (0 >= nSizeP) 
    { 
     nSize = 100; 
    } 
    else 
    { 
     nSize = nSizeP + 1; 
    } 

    pszForeverBuf = (char *) malloc((nSize + 1) * sizeof(char)); 

    return pszForeverBuf; 
} 

Вам нужно будет хранить значение pszForeverBuf где-то, так что, когда вы больше не хотите использовать память, вы можете освободить его с помощью pszForeverBuf - free(pszForeverBuf).

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

0

Во-первых, функции в C не могут возвращать значения массива, только указатели. Тогда вы не можете вернуть динамический «стек» выделенный объект, как уже отмечалось другими, поскольку такой объект перестает существовать, когда вы возвращаетесь из функции.

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

int* foo(int bar[3]) { 
    // fill the array here 

    return bar; 
} 

Это позволяет назвать вашу функцию с двумя различными стратегиями распределения

int* aMalloc = foo(malloc(sizeof(int[3]))); 
int* aLocal = foo((int[3]){ 0 }); 

и вы могли бы даже обернуть эти две формы в макросы, чтобы облегчить вашу кодировку:

#define fooMalloc() foo(malloc(sizeof(int[3]))) 
#define fooLocal() foo((int[3]){ 0 }) 

поэтому код выше, то будет читать

int* aMalloc = fooMalloc(); 
int* aLocal = fooLocal(); 
Смежные вопросы