2017-03-07 87 views
0

我的程序需要确定一个指针s1是否有来自s2的任何字符,然后返回一个指向s1中该位置的指针,否则返回NULL。无法理解这个const指针错误

#include <stdio.h> 

char * strpbrk(const char *, const char *); 

int main(void){ 
const char *s1 = "hello"; 
const char *s2 = "world"; 

printf("Repeated character in s1 is %p", *strpbrk(s1, s2)); 

} 

char * strpbrk(const char * s1, const char * s2){ 
char *p1, *p2; 

p1 = s1; 
p2 = s2; 
for(; *p1 != '\0'; p1++){ 
    for(; *p2 != '\0'; p2++){ 
     if(*p1 == *p2){ 
      break; 
     } 
     else{ 
      return '\0'; 
     } 
    } 
} 
return p1; 
} 

请收到此错误:

test.c: In function ‘strpbrk’: 
test.c:16:5: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers] 
    p1 = s1; 
    ^
test.c:17:5: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers] 
    p2 = s2; 
+5

知道这是不是一个错误是很重要的,这是一个警告 - 这两者有很大的不同。警告的原因是因为你将'p1'和'p2'声明为'char'而不是'const char'。 –

+0

我看到警告,而不是错误。 –

+1

我认为这个消息很明显。你在一边有一个const指针,而在另一边有一个非const对象。你放弃了质量。 – StoryTeller

回答

0

摆脱编译器警告的最好办法是改变p1p2的指针为const char然后加铸当您返回p1。这样代码的读者将会看到你不打算修改字符串参数。

在我(希望)被解决的实现中还有一些错误。

char * strpbrk(const char * s1, const char * s2) { 
    const char *p1, *p2; 

    for (p1 = s1; *p1 != '\0'; p1++) { // out is a label 
     for (p2 = s2; *p2 != '\0'; p2++) { 
      if (*p1 == *p2) { 
       // Match found 
       return (char*)p1; 
      } 
     } 
    } 
    // No match found 
    return NULL; 
} 
+0

有没有这样的语法'爆发;'。 – aschepler

+0

@aschepler这就是我从Java编码15年以上所得到的结果。感谢您指出了这一点。代码修改。 –

+0

我相信演员会根据6.7.6.1调用指定不好的行为。指针类型不兼容。你不应该丢掉限定符。 – Lundin

0

这是在若干的标准库函数的不一致性,strpbrkstrstr等,它们具有非恒定指针返回到发现项的常量限定字符串内的标准的要求。当标准委员会决定为这些库函数的参数添加常量正确性时,标准委员会正在吸烟,但不是返回类型,我不知道。

有没有办法可以可靠地在标准C实现这样的功能,因为你不能从一个“合格的指针型”转换成“类型的指针”。 C11 6.7.6.1:

For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.

这就是为什么你不断收到编译器警告。违反这条规则被列为由(非规范)附件J未定义的行为:

Two pointer types that are required to be compatible are not identically qualified, or are not pointers to compatible types (6.7.6.1).

所以回答你的问题是,像strpbrkstrstr功能无法获得安全的和可移植的标准下,他们将实施必须通过使用非标准语言扩展或其他编程语言来实现。

声音的解决方案是忽略标准规定的函数声明,而是使用有理数的声明。无论是

char* strpbrk_rw (char* s1, const char* s2); // read/write parameter 

const char* strpbrk_ro (const char* s1, const char* s2); // read-only parameter