Могу ли я выполнять операции с массивом символов и отдельными символами после передачи по ссылке на другую функцию?

#c

#c

Вопрос:

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

Я не показываю исходный код, над которым я работал, но я думаю, что у меня есть пример программы, чтобы выделить то, с чем я борюсь

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

void changeArray(char **arr){
    printf("Array is %sn",*arr);
    printf("This character is %cn",*arr[0]);
    printf("This character is %cn",*arr[1]); //segmentation fault here
    printf("This character is %cn",arr[2]);
    printf("This character is %cn",arr[3]);
    printf("This character is %cn",arr[4]);
    *arr = "bingo";
    printf("Array is %sn",*arr);
    printf("This character is %cn",arr[0]);
    printf("This character is %cn",arr[1]);
    printf("This character is %cn",arr[2]);
    printf("This character is %cn",arr[3]);
    printf("This character is %cn",arr[4]);
}

int main(int argc, const char* argv[]){
    char *blah = "hello";
    printf("Array is %sn",blah);
    printf("This character is %cn",blah[0]);
    printf("This character is %cn",blah[1]);
    printf("This character is %cn",blah[2]);
    printf("This character is %cn",blah[3]);
    printf("This character is %cn",blah[4]);
    changeArray(amp;blah);
    printf("This character is %cn",blah[0]);
    printf("This character is %cn",blah[1]);
    printf("This character is %cn",blah[2]);
    printf("This character is %cn",blah[3]);
    printf("This character is %cn",blah[4]);
    printf("Array is %sn",blah);
    return 0;
}
 

Это вывод программы, первый индекс в массиве символов, похоже, печатает букву «h», как я и ожидал, но любой другой индекс заставляет меня выходить за рамки:

 Array is hello
This character is h
This character is e
This character is l
This character is l
This character is o
Array is hello
This character is h
Segmentation fault
 

Комментарии:

1. Попробуйте (*arr)[1]

2. Или избавьте себя от лишних хлопот, объявив локальную переменную as char *ptr = *arr; , а затем используя ptr[0] , ptr[1] , и т.д. Конечно, вам нужно поддерживать локальную переменную в актуальном состоянии. Итак, после *arr = "bingo"; того, как вам ptr = *arr; снова понадобится.

3. Спасибо! Похоже, это работает для printf. Тогда это проблема приоритета оператора? Разыменование адреса должно выполняться до индексации в массив? Теперь, когда я думаю об этом, имеет смысл сделать это первым. Есть ли какая-то причина, по которой это не сработает, скажем, для сравнения строк? В моем исходном коде есть что-то вроде этого: strcmp((* bus_device_func)[4],»:»)

4. (*bus_device_func)[4] это один символ, а не строка. Таким образом, сравнение if ((*bus_device_func)[4] == ':')

5. Отлично, спасибо! Это проясняет возникшую у меня путаницу. Мой исходный код теперь выполняет то, что я намеревался.

Ответ №1:

У вас проблема с порядком операций. Приоритет оператора указывает, что [] операция выполняется до разыменования указателя, поэтому вы, по сути, перешли ко второму указателю в массиве символьных указателей, а затем разыменовали первый элемент. Вы хотите, чтобы запуск (*arr)[1] обрабатывался arr как указатель на массив, а не как массив указателей.

https://en.cppreference.com/w/cpp/language/operator_precedence

Ответ №2:

Приоритет оператора подстрочного индекса массива ( [] ) выше, чем у оператора разыменования указателя ( * ). Так *arr[1] что это эквивалентно *(arr[1]) . Но arr имеет только один элемент (это просто адрес blah ), поэтому arr[1] к нему нельзя получить доступ (не говоря уже о разыменовании).

Чтобы достичь желаемого, вам придется либо использовать круглые скобки ( (*arr)[1] ), либо использовать оператор подстрочного индекса вместо оператора разыменования для разыменования верхнего уровня ( arr[0][1] ).