C:不兼容的指针类型正在初始化

C:不兼容的指针类型正在初始化,c,arrays,pointers,C,Arrays,Pointers,我正在尝试学习C语言。我目前正在学习指针,所以我决定写一些代码来看看它是如何工作的。但是,代码按预期工作(即,它在数组中添加字符a-j并在控制台上打印),但我收到了有关不兼容指针分配的警告。我添加了警告,因为在给出警告的行上有注释 #include <stdio.h> #include <stdlib.h> int main(int argc, const char * argv[]) { #define MAX 10 char* c[MAX];

我正在尝试学习C语言。我目前正在学习指针,所以我决定写一些代码来看看它是如何工作的。但是,代码按预期工作(即,它在数组中添加字符a-j并在控制台上打印),但我收到了有关不兼容指针分配的警告。我添加了警告,因为在给出警告的行上有注释

#include <stdio.h>
#include <stdlib.h>


int main(int argc, const char * argv[]) {

    #define MAX 10

    char* c[MAX]; // pointer to the 1st element in the array
    char* pointer = &c; // Warning: Incompatible pointer types initializing 'char *' with an expression of type 'char *(*)[10]'
    for (int j = 0; j < 10; j++)
    {
        *pointer = 'a' + j;
        pointer++;
    }

    pointer = &c; // Warning: Incompatible pointer types assigning to 'char *' from 'char *(*)[10]'
    for (int j = 0; j < 10; ++j)
    {
        printf("i[%d] = %c\n", j, *pointer);
        ++pointer;
    }

    return 0;
}
我理解我写的代码如下:声明一个名为pointer的字符指针,并将数组中第一个元素的地址分配给指针

PS!请不要评论如何用更好的代码实现相同的结果,因为我在这里试图学习指针和数组。所以,虽然这可能是一个冗长的方式来实现这个结果,我觉得它在语法上是正确的,所以如果我有这个错误,请帮助我理解

变化:

char* pointer = &c

c
元素类型是
char*
&c
类型是指向
c
类型的指针

编辑:这将修复您的警告,但问题是您首先处理的是错误的类型

而不是:

char* c[MAX];
char* pointer = &c;
使用:

在您的程序中,您正在存储字符,因此您需要一个
char
数组,而不是
char*
元素数组


对于
pointer=&c必须是
指针=c
c
是指向
char
的指针数组:

char* c[MAX];
此表达式的类型

&c
是“指向长度的指针-
MAX
指向字符的指针数组”,或

编译器警告您正在从另一种类型初始化一种类型的指针

目前还不清楚您打算对代码执行什么操作,但是不进行转换的
char*
的有效初始化将是

char* pointer = c[0];
来自
&c
(指向指针数组的指针)的有效初始化将是

char *(*pointer)[MAX] = &c;
或者,您可以通过省略运算符
&
”的地址,让数组“衰减”到指向其第一个元素的指针,但这会生成指向指针的指针:

char** pointer = c;

从代码来看,您似乎以错误的方式声明了数组,应该是这样的

char c[MAX];
这是一个
char
数组,而不是
char
指针数组,那么

char *pointer;
pointer = c;
其中
pointer
是指向
c
的第一个元素的指针,代码的其余部分将按预期工作


另外,我有点好奇为什么要在
main()中定义
MAX
,以防万一你不知道,它不会被声明,而是在编译之前被预处理器替换,所以你把它放在代码中的位置是完全不相关的。

在你的C职业生涯的这个阶段,如果编译器不同意你关于某件事情是否有效的看法,那么就假设编译器是正确的。它对C的了解比你想象的要多o并且你发现编译器中错误的机会微乎其微。(注意C是一种区分大小写的语言;习惯于在适当的地方键入问题和大写字母的代码。而且语言是C,而不是“C”。)@Jonathan完全同意,这就是我提出这个问题的原因。代码实际上做了我希望它做的事情,但如果编译器抱怨,我肯定没有理解某些东西。谢谢,但为什么?这不是一回事吗?即char*pointer=&c[0];这行只是表示指针指向数组中的第一个元素。与char*pointer=&c;相同,为什么我会收到警告?@Sheedy75,因为
&c
的类型不是
char*
。请参见我的答案。@Sheedy75
char*c[MAX];char*pointer=&c[0];
因为这里
c[0]
的类型是
char*
(它是
char*
!)数组的元素),因此
&c[0]
将获取一个指向该元素的指针,这意味着一个
char**
.FYI-在Xcode main.c文件中添加这一行,我会得到以下警告:不兼容的指针类型初始化“char*”,使用类型为“char**”的表达式;删除&这是我第一次阅读本章时编写代码的方式,但让我困惑的是我读到了该char*c[MAX];只声明了一个指向数组中第一个元素的指针。因此,从我的基本理解来看,这只是保存了c[0]的内存地址;我决定今天使用Xcode,因为它给了我智能感知(我以前使用过gedit),Xcode抱怨,不让我编译代码。例如,“使用未声明的标识符'MAX'"-如果我在主函数之外声明它。但是我理解预处理器部分。也许我要回到gedit和Makefiles,或者尝试看看
Xcode
是否可以配置为理解预处理器宏,qtcretor有一个智能解析器,它可以知道预处理器宏是否被Makefile启用或禁用。是的在Xcode中,您可以转到构建设置并将“预编译头使用构建目录中的文件”设置为否。
char *(*pointer)[MAX] = &c;
char** pointer = c;
char c[MAX];
char *pointer;
pointer = c;