«Почему они должны отсылать его (указатель указателя на указатель) в первую очередь? Почему бы просто не просто направить их (указатель на указатель)?»
Им нужно бросить его, что это такое. Если предположить, что значение приходя в точках на ячейку памяти 10000, то есть что-то вроде этого:
(char **)
a address a
"points to"
*a **a
mem 1000 mem 10000 mem 20000
to mem 1007 to mem 10007
_____________ _____________ _______________
pointer var --> char pointer -> char
10000 20000 'a'
_____________ _____________ _______________
Если вы приводите его к (символ *) вы рассказываете компилятор , что адрес, на который ссылается (в этом случае 10 000) является символом. Это неверно.
(char *) address a points
a to
mem 1000 mem 10000 mem 20000
to mem 1007
_____________ ______ ________________
pointer var --> "char" unreachable char
10000 ? 'a'
_____________ ______ ________________
«Что смысл литья (указатель), чтобы (указатель на указатель) Если я
обугленного * х =„строка“; если я кастинг х
(char **) x; // что это? Этот персонаж '?"
То, что существует в этом примере, что-то вроде:
x *x or x[0] x[1] x[2] x[3] x[4] x[5] x[6]
mem 15000 mem 30000 mem 30001 mem 30002 mem 30003 mem 30004 mem 30005 mem 30006
to 15007
char * char char char char char char char
_________ _________ _________ _________ _________ _________ _________ _________
30000 --> 's' 't' 'r' 'i' 'n' 'g' '\0'
________ _________ _________ _________ _________ _________ _________ _________
Если компилятора, что х является символом **, то он думает, что это является картиной:
x *x or x[0] **x
char *
mem 15000 mem 30000 "char"
to 15007 to 30007
__________ _________ _________
30000 --> "string\0?"
converted to
pointer value -> ??
__________ _________ _________
Это неверно заканчивается тем, что касается «адреса» первых 8 байтов, начиная с 30000, доходит до «персонажа». Но так как 30000 - это начало o f символьный массив с нулевым символом, в лучшем случае он переходит в некоторую часть памяти и получает некоторый случайный байт, считая его действительным символом. В худшем случае он получит адрес, который недействителен для этой программы, вызывая фатальную ошибку при попытке получить к ней доступ.
так может я просто сделать
return strcmp((char *)a, (char *)b);
Нет, потому что б не символьные указатели. Для того, чтобы получить полукокс указатели вы не можете избежать:
return strcmp(*(char**)a, *(char**)b);
Используя пример Линдены вы могли бы назвать так:
#include <stdio.h>
#include <string.h>
int StrCmp(const void *a, const void *b){
char *s1 = *(char**) a;
char *s2 = *(char**) b;
printf("s1:%s\n",s1);
printf("s2:%s\n",s2);
return strcmp(s1,s2);
}
const char* arr_of_ptr[] =
{
"hello",
"world"
};
const char **p_arr_of_ptr = arr_of_ptr;
int main(void)
{
const char *cstring1 = "LaDonna";
const char *cstring2 = "McPherson";
const char **pcstring1 = &cstring1;
const char **pcstring2 = &cstring2;
StrCmp(&arr_of_ptr[0],&arr_of_ptr[1]);
StrCmp(pcstring1,pcstring2);
StrCmp(p_arr_of_ptr,p_arr_of_ptr + 1);
}
Где у вас этот код? Он выглядит непристойно взломанным ... – Mysticial
Я думаю, что это должна быть функция сравнения qsort для сортировки строк ... – nneonneo
Это действительно оболочка для функций qsort/bsearch или для сохранения какого-либо интерфейса. Вы должны обязательно писать такие обертки, передавая массив указателей на qsort/bsearch, если вы передадите нормальный strcmp(), код сработает и сгорит. – Lundin