Почему нельзя использовать int (* p) [] в качестве аргумента для функции C? - PullRequest
0 голосов
/ 23 сентября 2018
#include <stdio.h>
void print(int (*p)[3]);
int main(void)
{
    int a[3] = {1, 2, 3};
    print(&a);

    return 0;
}
void print(int (*p)[3])
{
    for (int i = 0; i < sizeof(*p) / sizeof(**p); i++)
        printf("%d\n", (*p)[i]);
}

Я написал функцию C.См. Выше.

Он может печатать все элементы в массиве.

Есть одна вещь, которая не так совершенна: количество элементов массива, кажется, известно заранее.

Итак, я сделал некоторые изменения в надежде сделать функцию универсальной:

#include <stdio.h>
void print(int (*p)[]);
int main(void)
{
    int a[3] = {1, 2, 3};
    print(&a);

    return 0;
}
void print(int (*p)[])
{
    for (int i = 0; i < sizeof(*p) / sizeof(**p); i++)
        printf("%d\n", (*p)[i]);
}

В функции p - указатель, указывающий на весь массив.

Однако онне может быть скомпилировано.

Почему нельзя использовать int (* p) [] в качестве аргумента для функции C?

Ответы [ 3 ]

0 голосов
/ 23 сентября 2018

Краткий ответ: int (*p)[] нельзя использовать в качестве аргумента, и функция должна волшебным образом знать размер массива, потому что стандарт так говорит.

Более длинный ответ:

int (*p)[] является указателем на массив, но массив не имеет определенного размера.Поэтому, глядя на массив, невозможно выполнить арифметику с указателями, вычислить размер объекта, на который указывает p, и т. Д.

У вас нет массива массивов, поэтому вам не нужно int (*p)[].У вас есть массив int, так что int *p или int p[] должно быть достаточно.Это не решает проблему знания размера вашего массива в print.Для этого у вас в основном есть 3 варианта

  1. Жесткий код значения в функции
  2. Поместите значение часового в ваш массив, чтобы отметить конец
  3. Passразмер как отдельный параметр, подобный этому:

    void print (int n, int p [n])

Просто помните, что какой бы метод вы ни использовали, передача параметровМассивы всегда будут использовать указатели за кулисами, поэтому вы НЕ МОЖЕТЕ использовать sizeof(p) для вычисления размера массива.sizeof всегда будет возвращать размер указателя в таких ситуациях

0 голосов
/ 23 сентября 2018

Проблема в том, что int [] является неполным типом, так как массив не имеет определенного размера и поэтому его sizeof не может быть получен.

В "современном C" (то есть в течение почти двух десятилетий) вы могли бы использовать для этого массивы переменной длины - вы можете передать размер в качестве аргумента, а затем массив:

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

void print(size_t n, int (*p)[*]);

int main(void) {
    int a[3] = {1, 2, 3};
    print(3, &a);
}

void print(size_t n, int (*p)[n]) {
    for (size_t i = 0; i < sizeof(*p) / sizeof(**p); i++)
        printf("%d\n", (*p)[i]);
}

Конечно, это ничего не дает, так как sizeof *p / sizeof **pp будет ... n.Следовательно, мы могли бы также использовать

void print(size_t n, int p[n]) {
    for (size_t i = 0; i < p; i++)
        printf("%d\n", p[i]);
}

, который меньше печатает.

0 голосов
/ 23 сентября 2018

int (*p)[] может использоваться в качестве аргумента для функции.Часть вашего кода, которая выдает ошибку, является sizeof *p, что, очевидно, невозможно, потому что тип *p равен int[], который является неполным типом и, следовательно, не имеет известного размера.

ДляЧтобы узнать длину массива, вы должны спроектировать способ получения этой информации.Опции включают в себя:

  • что вы сделали в исходном коде.
  • , передавая длину в качестве другого аргумента.
  • включая длину в качестве элемента массива.
  • со значением часового в конце массива.

Наиболее распространенной идиомой является передача int *p, size_t n, вы ничего не получите, используя указатель на массив безразмерность дана.

...