Например прохождения char* str
в функцию, которая принимает void *ptr
Пожалуйста, объясните, недействительные указатели в C
Я понимаю, что для того, чтобы передать это мне нужно пройти как:
fnc(&str)
и один раз внутри fnc(void *ptr)
функция мне нужно разыменованием использовать его
fnc(void *ptr){
*(char **)ptr = other string
}
Я узнал об этом путем проб и ошибок, но никогда не понимал, почему это на самом деле
Что означает *
снаружи? Как насчет 2 *
внутри (char __)?
Редактировать:
, например, функция обратного вызова передается str1 как «& ул» и str2 как «адрес на массив, первый элемент представляет собой символ *»
lfind(&str, arr, ...., cmp);
, который идет в
int cmp_str_ptr(const void *str1, const void *str2){
return strcmp(*(char **)str1, *(char **)str2);
}
Что я действительно интересно, хотя это то, что * означает, на каждом уровне косвенности. * (char *) str1 vs * (char **) str1 vs * (char) str1, если последний является действительным и даже комбинациями с * (char *) & str1.
Что означает * вне круглой скобки относительно единицы внутри. Независимо от используемых функций, я хочу знать, что это значит.
Final Edit:
Благодаря Майке за помощь мне решить эту проблему, я теперь понимаю, что реальная проблема заключается в напечатанном и не обязательно в указателях вообще. Я прочитал K & R - язык программирования c, но я до сих пор не понял.
В заключение я спросил, почему strcmp необходимо * (char **) str1 в качестве значения, и после ответа Майка я вижу, что он отличен как указатель на char *, поэтому его нужно разыменовать так, следовать за strcmp (char * s1, char * s2) reqs.
Причина, по которой lfind передал первый аргумент как & str, по-прежнему мне неизвестен, кроме создания сходства по функции обратного вызова (две разметки для символа **, а не одно нажатие и одно разыменование). Я предположил это из ответа Джонатана, где он упоминает, что нет необходимости использовать функцию * (char **) внутри функции.
Еще раз спасибо за помощь. И извините за относительно глупый вопрос.
Код, который вы опубликовали, вызывает неопределенное поведение (хотя он довольно часто встречается в реальном коде! Полагаясь на то, что компиляторы не выполняют оптимизаций, которые им разрешено выполнять). Это улучшит ваш вопрос, если вы сможете показать полный рабочий пример, показывающий, что вы имеете в виду. Функции 'strstr' и т. Д. Не используют эту технику –
Несколько неправильных представлений ... (1) Вам не обязательно использовать' fnc (& str) '- использование' fnc (str) 'было бы достаточно для многих целей; (2) один раз внутри функции, не обязательно, чтобы вы использовали '* (char **) ptr;' внутри функции; (3) 'strstr()' и 'strcmp()' не принимают аргументы 'void *'. То, что вы описываете, может быть правильным, если вызываемая функция должна изменить указатель в вызывающей функции, но для этого требуется передать указатель на указатель как «void *», что на самом деле не так, как вы предложили. –
В круглых скобках: 'char **' - это всего лишь тип. Поместив тип в круглые скобки, вы создали * typecast *. Это указатель на указатель на символ. Вне круглых скобок есть * разыменование *; то есть вы получаете доступ к указателю 'char *', на который указывает 'char **'. – mpontillo