C 来自不兼容指针类型的赋值警告

C 来自不兼容指针类型的赋值警告,c,pointers,C,Pointers,我正在读一本名为“Advanced_C”的书,并尝试编译示例代码“POINTERS.C” 我已经从代码块构建并运行了它,还尝试了从linux进行cc,但我收到了一条警告“来自不兼容指针类型的赋值” #包括 #包括 int main(无效); int main() { int n计数器=33; int*pnCounter=(int*)NULL; char szSaying[]= { “费尔斯通预测定律:\n” “Chicken Little只需正确一次。\n\n” }; char*pszSayin

我正在读一本名为“Advanced_C”的书,并尝试编译示例代码“POINTERS.C”

我已经从代码块构建并运行了它,还尝试了从linux进行cc,但我收到了一条警告“来自不兼容指针类型的赋值”

#包括
#包括
int main(无效);
int main()
{
int n计数器=33;
int*pnCounter=(int*)NULL;
char szSaying[]=
{
“费尔斯通预测定律:\n”
“Chicken Little只需正确一次。\n\n”
};
char*pszSaying=(char*)NULL;
printf(
“n计数器| pnCounter |*(pnCounter)| pszSaying |”
“SZSAY[0]| SZSAY[0-20]\n”);
printf(“%8d |%8p |%8d |%8p |%c |%20.20s\n”,
反对者,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
Szsay);
printf(“pnCounter=&nCounter;\n”);
pnCounter=&n计数器;
printf(“%8d |%8p |%8d |%8p |%c |%20.20s\n”,
反对者,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
Szsay);
printf(“pszSaying=szSaying;\n”);
pszSaying=szSaying;
printf(“%8d |%8p |%8d |%8p |%c |%20.20s\n”,
反对者,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
Szsay);
printf(“pszSaying=&szSaying;\n”);
pszSaying=&szSaying;
printf(“%8d |%8p |%8d |%8p |%c |%20.20s\n”,
反对者,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
Szsay);
printf(“pszSaying=&szSaying[0];\n”);
pszSaying=&szSaying[0];
printf(“%8d |%8p |%8d |%8p |%c |%20.20s\n”,
反对者,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
Szsay);
printf(“*(pnCounter)=1234;\n”);
*(pnCounter)=1234;
printf(“%8d |%8p |%8d |%8p |%c |%20.20s\n”,
反对者,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
Szsay);
返回(0);
}
我是C编程新手


谢谢

szSaying
声明为
char
s的数组,
pszSaying
声明为指向
char
的指针。在表达式中:

pszSaying = szSaying,
szSaying
是一个数组,它被转换为指向
char
的指针,并且对
pszSaying
的赋值是有效的。但是,在espression中:

pszSaying = &szSaying
&szSaying
是指向
char
s数组的指针。这与指向
char
的指针不同。这就是警告不兼容指针类型的原因

这是使用gcc file.c-std=c99-Wall-Wextra-pedantic编译时得到的唯一警告。嗯,在调用
printf()
时,也有大量关于
%p
格式说明符的警告。在打印它们的值之前,您应该

通过在打印前将所有指针强制转换为
(void*)
,并修改这些行:

char (*parrSaying)[] = NULL;

...

printf("parrSaying = &szSaying; \n");
parrSaying = &szSaying;

printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
       nCounter,
       (void *) pnCounter,
       *(pnCounter),
       (void *) parrSaying,
       (*parrSaying)[0],
       szSaying);
所有警告都将被删除。这里,
char
被声明为指向
char
s数组的指针,并初始化为NULL。但是,在处理了警告之后,还有另一个问题:您正在尝试取消对空指针的引用!很好,您正在初始化指向NULL的指针(尽管没有理由将NULL强制转换为
(char*)
或其他内容),因为如果不这样做,这些解引用将访问内存中的一些随机位置。但取消引用空指针是未定义的行为。您需要移动这两个指针指定,以便它们在第一次尝试取消引用和打印其值之前发生:

pnCounter = &nCounter;
pszSaying = szSaying;
进行这些更改后,您的代码将在没有警告的情况下编译并在我的系统上运行,并提供以下输出:

nCounter | pnCounter | *(pnCounter) | pszSaying | szSaying[0] | szSaying[0-20]
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
pnCounter = &nCounter; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
pszSaying = szSaying; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
parrSaying = &szSaying; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
pszSaying = &szSaying[0]; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
*(pnCounter) = 1234; 
    1234 | 0x7ffd3bd36bc4 |     1234 | 0x7ffd3bd36be0 | F | Firestone's Law of F

pszSaying=&szSaying
pszSaying
是一个
char*
szSaying
是一个
'char**
下次缩小你的问题范围,发布一个。首先
*(pszSaying)
取消引用空值。@MichaelWalz:
szSaying
是一个
char[某物]
。而
&szSaying
char(*)[某物]
。这里没有
char**
。初始化
szSaying
时的
{
括号
}
有误导性。大括号之间实际上是单个字符串文字(因为相邻的字符串文字是串联的)。在我注意到没有逗号之前,我一直认为它是两个字符串文本,这适合
char*szSaying[]
nCounter | pnCounter | *(pnCounter) | pszSaying | szSaying[0] | szSaying[0-20]
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
pnCounter = &nCounter; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
pszSaying = szSaying; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
parrSaying = &szSaying; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
pszSaying = &szSaying[0]; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
*(pnCounter) = 1234; 
    1234 | 0x7ffd3bd36bc4 |     1234 | 0x7ffd3bd36be0 | F | Firestone's Law of F