2015-10-30 9 views
-2

Например прохождения 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 **) внутри функции.

Еще раз спасибо за помощь. И извините за относительно глупый вопрос.

+2

Код, который вы опубликовали, вызывает неопределенное поведение (хотя он довольно часто встречается в реальном коде! Полагаясь на то, что компиляторы не выполняют оптимизаций, которые им разрешено выполнять). Это улучшит ваш вопрос, если вы сможете показать полный рабочий пример, показывающий, что вы имеете в виду. Функции 'strstr' и т. Д. Не используют эту технику –

+2

Несколько неправильных представлений ... (1) Вам не обязательно использовать' fnc (& str) '- использование' fnc (str) 'было бы достаточно для многих целей; (2) один раз внутри функции, не обязательно, чтобы вы использовали '* (char **) ptr;' внутри функции; (3) 'strstr()' и 'strcmp()' не принимают аргументы 'void *'. То, что вы описываете, может быть правильным, если вызываемая функция должна изменить указатель в вызывающей функции, но для этого требуется передать указатель на указатель как «void *», что на самом деле не так, как вы предложили. –

+1

В круглых скобках: 'char **' - это всего лишь тип. Поместив тип в круглые скобки, вы создали * typecast *. Это указатель на указатель на символ. Вне круглых скобок есть * разыменование *; то есть вы получаете доступ к указателю 'char *', на который указывает 'char **'. – mpontillo

ответ

0

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

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

Если вы хотите использовать это местоположение, вы должны сообщить компилятору, к какому типу указывается указатель void, указав соответствующий указатель.

+0

Вы вместе с некоторыми комментариями (Майк и Джонатан Леффлер) выше помогли мне. Большое спасибо за это –

+0

Почему downvotes? – RedX

+0

Вы никогда не получите ответ на этот RedX. Люди недовольны, когда написанное не соответствует их миру. Я поддержал вас, вы должны были ответить, и ваш ответ в порядке, и он соответствует уровню понимания OP. – Elyasin