#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]
).