Как использовать аргументы функции для объявления массива внутри функции?Объявление массива в C
Мой код:
double function_2(int a)
{
int t[a];
}
возникает ошибка:
Expression must have a constant value.
Как использовать аргументы функции для объявления массива внутри функции?Объявление массива в C
Мой код:
double function_2(int a)
{
int t[a];
}
возникает ошибка:
Expression must have a constant value.
Вы не можете назначить его непосредственно. Вы должны объявить его фиксированной константой.
В противном случае используйте понятие указателя.
Вместо массива вы должны использовать распределение памяти и использовать его как массив для итерации или другого использования.
Ваш код является полностью действующим кодом C.
Вы используете VLA (массив переменной длины). Это функция c99, и вам нужно обеспечить, чтобы ваш компилятор поддерживал код c99.
Если вы используете gcc
, по умолчанию gcc
установлен в -std=gnu89
, который является расширениями C89 + GNU. Используйте -std=c99
или -std=gnu99
с gcc
, чтобы скомпилировать вашу программу.
Если вы используете MSVC, к сожалению, он не поддерживает c99, поэтому вы не можете использовать функцию c99 с этим компилятором.
EDIT:
Если ваш компилятор не поддерживает VLA вы можете использовать динамическое выделение памяти вместо:
#include <stdlib.h>
double function_2(int a)
{
// Allocate array object
int *t = malloc(a * sizeof *t);
if (!t) {
// Handle malloc errors
}
// Write your program here: ...
// Free array object
free(t);
}
Хотя это правильно, вы также должны предоставить решение (динамическая память с использованием 'malloc' или больше похожа на VLA, используя' alloca' для резервирования памяти стека). Это сделало бы его идеальным ответом :) –
@NiklasB. Я согласен, что информация о 'malloc' актуальна, и я добавляю ее. Что касается 'alloca', это стандартная функция non C. – ouah
Да, но я думаю, что он может быть использован в качестве обходного пути в MSVC, который использует OP. –
C99 имеет расширение для variable length arrays. При компиляции кода с помощью следующей команды, он будет работать:
gcc -std=gnu99 lala.c -o lala
Если вы используете VC++, массивы переменной длины нет, так как стандарт использует это C89 с некоторыми особенностями C99 (не включая переменные длина массивов).
Поскольку вы упоминаете компиляции с VC++ я добавлю несколько замечаний:
.c
вместо .cpp
Использование динамического распределения, чтобы сделать эквивалент того, что вы пытаетесь:
int * t = malloc(a * sizeof(int))
Если вы используете динамическое распределение и хотите вернуть массив, вы можете сделать это за счет того, возвращаем функцию int *
, а затем возвращаем t
.Однако, если вы это делаете, это также возвращает длину массива (если только это не фиксированная известная длина). Общие методы, используемые для возврата этой длины:
Например:
// Returns number of entries in the Lala array returned from b()
int GetNumLalaEntries(void);
// Function b which returns an array.
int * b(void)
{
int * lala = malloc(5 * sizeof(int *));
...
return lala;
}
В приведенном выше случае, GetNumLalaEntries
возвращает 5 всегда, но если это число было динамичным, что необходимо будет генерироваться из некоторой внутренней информации синхронизации.
Например:
// We are passing in the array this time.
void b(int * lala)
{
... // Do whatever you need with lala
}
int main(void)
{
int * lala = malloc(GetNumLalaEntries() * sizeof(int *));
b(lala);
return 0;
}
struct
вместо которого как указатель массива и размер массива.Например:
struct lala_encapsulation {
int * lala;
int lala_entries;
};
struct lala_encapsulation b(void)
{
struct lala_encapsulation le;
le.lala_entries = 5;
le.lala = malloc(le.lala_entires * sizeof(int *));
return le;
}
Последний метод позволяет вернуть весь массив, обернув его в struct
, который может быть возвращен по значению.
Спасибо, я следил за комментариями. Вопрос: если возвращаемый тип функции является массивом, как я могу использовать * t (указатель) для возврата массива t? – holy
@holy: Отредактировал мой ответ, чтобы включить возвращаемый массив. –
: Это часть моего кода: JNIEXPORT jintArray JNICALL Java_MainClass_intArrayMethod (JNIEnv * env, jobject obj, jfloatArray array, jint nb_of_subscribers, jint tags) {jsize len = (* env) -> GetArrayLength (env, array); jint * body = (* env) -> GetIntArrayElements (env, array, 0), после чего я сделал некоторые изменения в body [], и я хочу вернуть все данные, указанные телом. Есть ли способ сделать это? – holy
double function_2(int a)
{
int * t = (int*)malloc(sizeof(int)*a);
for(int i = 0; i<a; i++)
{
// do your work here, accessing t like an array
t[i]=...
}
free(t);
...
}
Вы должны использовать кучу (таНос/бесплатно)
#include<stdlib.h>
double function_2(int a)
{
....
int *t = (int*) malloc (sizeof(int) *a);
t [1] = 1; // but check if array is large enough
...
free (t);
...
return 0.0;
}
Несмотря на то, что вы разочарованы и устарели, вы все равно можете использовать стек для распределений по размеру с помощью ['alloca'] (http://www.gnu.org/software/libc/manual/html_node/Advantages-of-Alloca.html), когда VLA не поддерживаются. –
возможный дубликат [Инициализация массива после заявления] (http://stackoverflow.com/questions/2816765/initializing-an -array-after-declaration) – mdm
Вы уверены, что используете компилятор C? Обратите внимание, что массивы переменной длины являются расширениями GNU до C99. –
@mdm: Это не обязательно дубликат. Другие ответы на связанный с вами вопрос предлагают только динамическое распределение, потому что в нем явно указано C89, где не существует понятия массивов переменной длины. –