Подтвердить что ты не робот

C размер переданного массива

Возможный дубликат:
Как найти sizeof (указатель, указывающий на массив)

Я понимаю, что оператор sizeof оценивается и заменяется константой во время компиляции. Учитывая, что может ли функция, передаваемая разными массивами в разных точках программы, вычислить ее размер? Я могу передать его как параметр функции, но мне не нужно добавлять другой параметр, если мне не обязательно.

Вот пример, иллюстрирующий то, что я прошу:

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

#define SIZEOF(a) ( sizeof a / sizeof a[0] )


void printarray( double x[], int );

int main()
{
        double array1[ 100 ];


        printf( "The size of array1 = %ld.\n", SIZEOF( array1 ));
        printf( "The size of array1 = %ld.\n", sizeof array1 );
        printf( "The size of array1[0] = %ld.\n\n", sizeof array1[0] );

        printarray( array1, SIZEOF( array1 ) );

        return EXIT_SUCCESS;
}


void printarray( double p[], int s )
{
        int i;


        // THIS IS WHAT DOESN"T WORK, SO AS A CONSEQUENCE, I PASS THE 
        // SIZE IN AS A SECOND PARAMETER, WHICH I'D RATHER NOT DO.
        printf( "The size of p calculated = %ld.\n", SIZEOF( p ));
        printf( "The size of p = %ld.\n", sizeof p );
        printf( "The size of p[0] = %ld.\n", sizeof p[0] );

        for( i = 0; i < s; i++ )
                printf( "Eelement %d = %lf.\n", i, p[i] );

        return;
}
4b9b3361

Ответ 1

Нет волшебного решения. C не является отражающим языком. Объекты автоматически не знают, что они собой представляют.

Но у вас есть много вариантов:

  • Очевидно, добавьте параметр
  • Оберните вызов макросом и автоматически добавьте параметр
  • Используйте более сложный объект. Определите структуру, которая содержит динамический массив, а также размер массива. Затем передайте адрес структуры.

Ответ 2

Функциональные параметры никогда не имеют типа массива. Когда компилятор видит

void printarray( double p[], int s )

или даже

void printarray( double p[100], int s )

он преобразует либо один в

void printarray( double* p, int s )

Итак, sizeof(p) - sizeof(double*). И да, вам придется передать размер в качестве параметра.

Ответ 3

Проблема в том, что ваша функция не получает значение массива; он получает значение указателя.

За исключением случаев, когда это операнд операторов sizeof или унарных &, или это строковый литерал, используемый для инициализации другого массива в объявлении, выражение типа "массив из T" будет преобразованный в тип "указатель на T", и его значение будет адресом первого элемента массива.

Таким образом, когда вы вызываете printarray, тип array1 неявно преобразуется из "100-элементного массива double" в "указатель на double". Таким образом, тип параметра p равен double *, а не double [100].

В контексте объявления параметра функции T a[] идентичен T *a.

Вот почему вы должны передавать размер массива отдельно;

Ответ 4

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

Например, когда у вас есть строка, например:

char s1[] = "foobar";

На самом деле у вас есть массив длиной 7, причем седьмое пятно является нулевым завершающим char '\ 0', которое служит для обозначения конца массива/строки.

Другой способ сделать это - создать структуру, состоящую из размера, за которым следует массив.

Ответ 5

Вы ответили на свой вопрос. Он вычислялся во время компиляции, так как же "sizeof p" может иметь более одного значения во время выполнения?

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

Ответ 6

Вы должны либо

  • Передайте размер массива в качестве параметра функции
  • Убедитесь, что массив заканчивается известным значением и останавливается, когда вы достигаете этого значения.

Ответ 7

Если ваш массив имеет нулевой конец, вы можете выполнить итерацию по массиву и найти последнее значение. Многие строковые операторы в C работают таким образом

В противном случае у вас нет выбора.

sizeof вернет размер p, который является указателем и будет равен вашему размеру int