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

标签 c pointers

我正在读一本名为“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/

相关文章:

使用 C 指针和结构的链表程序中的冲突类型错误消息

c - 如何从字符串创建二叉搜索树?

c - 在 C 中将 strcpy 与字符串数组一起使用

c++ - 在 C/C++ 中初始化数组是好习惯吗?

c++ - 条件运算符的返回值

c++ - 指向存储在结构中的数组的指针在哪里?

c - 如何从 C 宏返回值?

c - MPI_Bcast 发送字符串

C 数组 malloc 未知大小

Objective-C 指针?