Передача массива строк как параметр к функции в C

, если final используется с объектами, вы не можете изменить ссылку на этот объект, но изменение значения отлично. Aray - это объект в java, и если вы хотите, чтобы значение объекта не изменялось, после его создания вам нужно будет сделать объект неизменным и примитивный массив нельзя сделать неизменным в java.

    final int [] finalArr={5,6,8};

     System.out.println("Value at index 0 is "+finalArr[0]);    
      //output : Value at index 0 is 5

      //perfectly fine
      finalArr[0]=41;

     System.out.println("Changed value at index 0 is "+finalArr[0]);
    //Changed value at index 0 is 41

     int[] anotherArr={7,9,6};
     // finalArr=anotherArr;
     //error : cannot assign a value to final variable finalArr

Подробнее о неизменяемом массиве вы можете обратиться к этим ссылкам:

Неизменяемый массив в Java

Есть ли способ сделать обычный массив неизменным в Java?

14
задан Mark Ransom 28 January 2009 в 01:38
поделиться

4 ответа

Предупреждение является точно правильным. Ваша функция хочет массив указателей. Вы даете ему массив массивов.

Ожидаемый:

 sep_foo:
 +------+       +-----+
 |char**|--> 0: |char*|-->"string1"
 +------+       +-----+
             1: |char*|-->"string2"
                +-----+
*sep_foo_qty-1: |...  |
                +-----+

, Что Вы обеспечили:

           sep_foo:
           +--------------------------------+
        0: | char[MAX_STRING_LENGTH]        |
           +--------------------------------+
        1: | char[MAX_STRING_LENGTH]        |
           +--------------------------------+
MAX_QTY-1: | ...                            |
           +--------------------------------+

массив с элементами типа X может "затухнуть" в pointer-to-X, или X*. Но значению [1 110] не позволяют измениться в том преобразовании. Только [1 122] один операция затухания позволяются. Вам был бы нужен он для случая дважды. В Вашем случае, X array-of-MAX_STRING_LENGTH - символы. Функция хочет X быть указателем на символ. Так как это не то же, компилятор предупреждает Вас. Я немного удивлен, что это было просто предупреждение начиная ни с чего хорошего, может прибыть из того, что компилятор позволил происходить.

В Вашей функции, Вы могли написать этот код:

char* y = NULL;
*sep_foo = y;

Это - свод законов, так как sep_foo char**, таким образом *sep_foo char* и так y; можно присвоить им. Но с то, что Вы пытались сделать, *sep_foo, не будет действительно быть char*; это указало бы на массив символа. Ваш код, в действительности, попытался бы сделать это:

char destination[MAX_STRING_LENGTH];
char* y = NULL;
destination = y;

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

существует два способа решить это:

  • Изменение путем Вы объявляете и выделяете sep_foo на стороне вызова, таким образом, это соответствует тому, что функция ожидает получать:

    char** sep_foo = calloc(MAX_QTY, sizeof(char*));
    for (int i = 0; i < MAX_QTY; ++i)
      sep_foo[i] = malloc(MAX_STRING_LENGTH);
    

    или, эквивалентно

    char* sep_foo[MAX_QTY];
    for (int i = 0; i < MAX_QTY; ++i)
      sep_foo[i] = malloc(MAX_STRING_LENGTH);
    
  • Изменение прототип функции для принятия то, что Вы действительно даете ему:

    int parse(const char *foo, char sep_foo[MAX_QTY][MAX_STRING_LENGTH], int *sep_foo_qty);
    
28
ответ дан 1 December 2019 в 06:35
поделиться

Параметр 2 должен быть

char sep_foo[][MAX_STRING_LENGTH]

Для разъяснения, Вы передаете указатель на синтаксический анализ () и рассматриваете его как указатель на указатель. Многомерный массив в C НЕ является массивом указателей. Это - единственный блок памяти, на которую указывает переменная типа массив. Вы не можете разыменовать его дважды.

15
ответ дан 1 December 2019 в 06:35
поделиться

sep_foo определяется как массив массивов. Другими словами, когда Вы используете sep_foo, это указывает на начало последовательной памяти. Вот модель:

(assume MAX_STRING_LENGTH = 16, MAX_QTY = 2)
sep_foo       = &&0000
sep_foo[0]    =  &0000
sep_foo[0][0] = *&0000 = 12
sep_foo[0][8] = *&0008 = 74
sep_foo[1]    =  &0010
sep_foo[1][0] = *&0010 = 12


0000  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE
0010  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE

Однако Ваша функция ожидает массив указателей (на самом деле, указателя на указатель). Это смоделировано как таковое:

sep_foo_arg       =   &&0000
sep_foo_arg[0]    =  *&&0000 = &0010
sep_foo_arg[0][0] =  *&*&0000 = 12
sep_foo_arg[0][8] = *(&*&0000 + 8) = 74
sep_foo_arg[1]    =  *&&0002 = &0020
sep_foo_arg[1][0] = *&*&0000 = 12

0000  0010 0020  xxxx xxxx  xxxx xxxx  xxxx xxxx

0010  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE
0020  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE

Да... Синтаксис может немного сбивать с толку мои объяснения...

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

int parse(const char *foo, char (*sep_foo)[MAX_STRING_LENGTH], int *sep_foo_qty);
4
ответ дан 1 December 2019 в 06:35
поделиться

Если это - Ваш точный код, то я предполагаю, что segfault из-за того, что Вы не выделили память char* token внутренняя часть Ваша функция синтаксического анализа и затем использование это в Вашем strcpy.

-2
ответ дан 1 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: