Ответ 1
Ваш фрагмент кода верен. Однако указатели и массивы в C действительно разные. Проще говоря, "указатель на тип T" не такой же, как "массив типа T".
Пожалуйста, посмотрите C Faq, обсуждая указатели и массивы, чтобы лучше понять это.
Я пишу небольшую программу на C, чтобы сделать хруст, и мне нужно передать массивы между функциями. Функции должны принимать и возвращать указатели, правильно?
Например, это (я знаю, что это не самая эффективная вещь):
int* reverse(int* l, int len) {
int* reversed = malloc(sizeof(*reversed)*len);
int i, j;
for (i = 0, j = len-1; i < len; i++, j--) {
reversed[j] = l[i];
}
return reversed;
}
Я правильно использую указатели?
Ваш фрагмент кода верен. Однако указатели и массивы в C действительно разные. Проще говоря, "указатель на тип T" не такой же, как "массив типа T".
Пожалуйста, посмотрите C Faq, обсуждая указатели и массивы, чтобы лучше понять это.
Ссылка на C-FAQ: Массивы и указатели уже предоставлены, но есть также подробное объяснение в C для Smarties: Массивы и указатели. Сначала вы можете прочитать страницу "Анализ выражений".
Несколько вещей о вашем примере, которые следует исправить:
int
вместо правильного size_t
для хранения размеров объектов.malloc()
.Один из способов "исправить" эту вторую проблему - позволить вызывающему абоненту решить, где хранится вывод (возможно, вызывающему не нужен или нужен только что выделенный массив):
int *reverse(int *out, int *l, size_t len) {
size_t i, j;
for (i = 0, j = len - 1; i < len; ++i, --j) {
out[j] = l[i];
}
return out;
}
С точки зрения низкого уровня массив представляет собой непрерывный кусок памяти, к которому обращается адрес начала этого фрагмента и смещения, поэтому из этого уровня абстракции это указатель. Однако, с точки зрения языка C, тип массива отличается от типа указателя. В основном массив может быть назначен на значение указателя, но он не тот же тип.
В целях вашей функции вы все в порядке.
В педантичной теории массивы и указатели - это разные вещи, поскольку массив задает область памяти, и поэтому размер массива является частью его типа. Таким образом, каждый говорит, что имя массива распадается на указатель при использовании в этом контексте. Подробное объяснение в C-FAQ.
На практике они одинаковы, так как формально a[i]
- это то же самое, что и *(a+i)
, и поэтому конец компилятора обрабатывает имя массива и указатель точно так же. Единственное различие, о котором стоит беспокоиться, заключается в том, что
void foo()
{
int a[5]; // allocates five words of space on the stack
int *b; // allocates *one* word of space on the stack (to hold the pointer)
}
Ваш фрагмент кода в порядке. Просто будьте осторожны, чтобы освободить память, чтобы ваша функция malloc()
была в том, кто ее называет.
массивы в C представлены и обрабатываются указателем на первый элемент, например
int arr[50];
int * ptr1 = arr;
int * ptr2 = &arr[0];
в этом примере, ptr1 == ptr2, потому что адрес первого элемента массива и базовый указатель для массива одинаков.
, поэтому ваш основной пример правильный, хотя я подозреваю, что malloc должен быть:
int* reversed = malloc(sizeof(int)*len);
Забастовкa >