[英]How to fix the “discard const” in c qsort function (the array is a pointer array), might related to the understanding of pointers
I'm learning C at the moment. 我现在正在学习C。 currently learning the c pointer (pointer arrays).
当前正在学习c指针(指针数组)。 What the below code (a prototype from C in a nutshell) trying to do is to read the text from stdin, line by line.
下面的代码(简而言之,是C语言的原型)试图做的是逐行从stdin中读取文本。 every array element is a pointer to one line of text, then sort the text by just sort the pointers.
每个数组元素都是一个指向一行文本的指针,然后通过仅对指针进行排序来对文本进行排序。 When I try to compile my code, the compiler (gcc) give me a warning of "discard const", I tried to add the cast (const char **) in the str_compare function, but still doesn't fix my problem
当我尝试编译代码时,编译器(gcc)发出警告“ discard const”,我尝试在str_compare函数中添加强制类型转换(const char **),但仍然无法解决我的问题
I think this might related to my understanding to c pointers. 我认为这可能与我对c指针的理解有关。 can someone help to point out where and i did wrong, what is the problem in my code please?
有人可以帮助指出我在哪里做错了吗,请问我的代码有什么问题?
I turned on a lot of warning flags and treat all the warnings as errors in gcc. 我打开了许多警告标志,并将所有警告视为gcc中的错误。 I can understand the pointers and I used qsort before, it all turned out fine.
我能理解这些指针,并且之前使用过qsort,结果一切都很好。 But this is the first time i code pointer to pointers.
但这是我第一次将指针编码为指针。 so I think i might have some misunderstanding here.
所以我想我可能对此有些误解。
// Read text line by line then sort them, use point array
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *getLine(void);
int str_compare(const void *, const void *);
#define NLINES_MAX 1000
char *linePtr[NLINES_MAX];
int main()
{
// Read lines;
int long unsigned n = 0;
for ( ; n < NLINES_MAX && (linePtr[n] = getLine()) != NULL; ++n)
;
if ( !feof(stdin))
{
if (n == NLINES_MAX)
fputs("sorttex: too many lines.\n", stderr);
else
{
fputs ("sorttext: error reading from stdin.\n", stderr);
}
}
else
{
qsort(linePtr, n, sizeof(char *), str_compare);
for ( char **p = linePtr; p < linePtr +n; ++p)
puts(*p);
}
return 0;
}
int str_compare(const void *p1, const void *p2)
{
return strcmp(*(const char **)p1, *(const char **)p2);
}
#define LEN_MAX 512
char *getLine()
{
char buffer[LEN_MAX], *lineP = NULL;
if (fgets (buffer, LEN_MAX, stdin) != NULL)
{
size_t len = strlen(buffer);
if (buffer[len-1] =='\n')
buffer[len-1] = '\0';
else
{
++len;
}
if ((lineP = malloc(len)) != NULL)
strcpy( lineP, buffer);
}
return lineP;
}
The gcc flags are: gcc标志是:
-std=c11 -pedantic-errors -pipe -O2 -Wall -Werror -Wextra -Wfloat-equal \\ -Wshadow -Wpointer-arith -Wcast-align -Wstrict-overflow=5 -Wwrite-strings \\ -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion \\ -Wunreachable-code -Winit-self -march=native
I expect to get rid of the "discard const" warning message 我希望摆脱“丢弃常量”警告消息
The argument passed to the str_compare
function is the address of the array element. 传递给
str_compare
函数的参数是数组元素的地址。 The array element has type char *
, and the caller of str_compare
will treat it as const, and then pass the address in. So, you will actually be receiving a char * const *
. 该数组元素的类型为
char *
,并且str_compare
的调用方将其视为const,然后将其传入地址。因此,您实际上将收到一个char * const *
。
So, the const void *
is actually 因此,
const void *
实际上是
pointer to a constant pointer to char
指向常量指针的指针
and NOT 并不是
pointer to a pointer to a constant char
指向常量char的指针
as you had coded. 如您所编码。
int str_compare(const void *p1, const void *p2)
{
char * const *pp1 = p1;
char * const *pp2 = p2;
return strcmp(*pp1, *pp2);
}
The line could be: 该行可能是:
return strcmp(*(char *const *)p1, *(char *const *)p2);
The items being sorted are pointers to char *
(Not pointers to const char *
as your code would say). 要排序的项目是
char *
指针(如您的代码所说,不是const char *
指针)。 And the inner const
is to ensure that the comparison function does not modify the objects being compared (which are the char *
objects, hence char * const
). 内部
const
是为了确保比较功能不会修改要比较的对象(它们是char *
对象,因此是char * const
)。
Of course, expanding it out with extra variables as shown by jxh is not a bad idea either. 当然,用jxh所示的额外变量扩展它也不是坏主意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.