gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 21:08:05 25 4
gpt4 key购买 nike

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

我已经从代码块构建并运行它,并且还尝试从 Linux 抄送,但我收到警告“来自不兼容的指针类型的分配”。

#include <stdio.h>
#include<string.h>

int main(void);

int main()
{

int nCounter = 33;
int *pnCounter = (int *)NULL;

char szSaying[] =
{
"Firestone's Law of Forecasting: \n"
"Chicken Little only has to be right once.\n\n"
};
char *pszSaying = (char *)NULL;

printf(
"nCounter | pnCounter | *(pnCounter) | pszSaying | "
"szSaying[0] | szSaying[0-20]\n");

printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
nCounter,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
szSaying);

printf("pnCounter = &nCounter; \n");
pnCounter = &nCounter;

printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
nCounter,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
szSaying);

printf("pszSaying = szSaying; \n");
pszSaying = szSaying;

printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
nCounter,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
szSaying);

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

printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
nCounter,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
szSaying);

printf("pszSaying = &szSaying[0]; \n");
pszSaying = &szSaying[0];
printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
nCounter,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
szSaying);

printf("*(pnCounter) = 1234; \n");
*(pnCounter) = 1234;

printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
nCounter,
pnCounter,
*(pnCounter),
pszSaying,
*(pszSaying),
szSaying);
return (0);
}

我是 C 编程新手。

谢谢!

最佳答案

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

pszSaying = szSaying,

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

pszSaying = &szSaying

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

这是我使用 gcc file.c -std=c99 -Wall -Wextra -pedantic 进行编译时收到的唯一警告。嗯,在调用 printf() 时,还有大量关于 %p 格式说明符的警告。你应该cast pointers to (void *)在打印它们的值之前。

在打印之前将所有指针强制转换为 (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);

所有警告均已删除。这里,parrSaying 被声明为指向 char 数组的指针,并初始化为 NULL。但是,处理完这些警告后,还有另一个问题:您正在尝试取消引用 NULL 指针!最好将指针初始化为 NULL(尽管没有理由将 NULL 转换为 (char *) 或其他),因为如果不这样做,这些取消引用将访问一些随机位置在内存中。但取消引用 NULL 指针是未定义的行为。您需要移动这两个指针赋值,以便它们发生在第一次尝试取消引用并打印其值之前:

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

关于c - 来自不兼容指针类型警告的赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40426148/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com