C语言关于出现错误代码C2040 间接寻址级别不同的问题

这里是小白,在研究数组与指针时发现了问题。
在主函数外进行如下声明后程序正常运行:

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

char str[30] = "Hello world";
char *ptr = str;

void main()
{}

而修改成如下却报错:

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

char str[30] = "Hello world";
char *ptr;
ptr = str;

void main()
{}

显示

C2040 “ptr”:“int”与“char *”的间接寻址级别不同

C4047 “初始化”:“int”与“char *”的间接级别不同

定义为int型仍然报类似的错 在VS2017与VC6环境情况相同

将两者放入主函数则都没有问题

新人懂得不多 希望各位能够详细解答 多谢了

这是一个关于在全局区赋值的经典问题

首先,C/C++语言规定,不允许在函数外部有赋值语句,并且允许初始化语句。
第二,这是因为在全局区的赋值语句执行顺序是没有保证的,如果强行编译,则可能因编译加载的文件顺序不同而结果不同。
第三,C/C++语言以及编译器规定,不允许用户在全局区修改静态数据内存空间,因此在全局区的赋值语句是不符合语言规范的。

在C/C++编译的程序占用的内存中,全局变量存储于全局区(static)也叫静态数据内存空间。
其中,初始化的全局变量和静态变量放一块区域,没有初始化的在相邻的另一块区域。


// 声明一个变量,同时分配内存并赋值
char *ptr = str;

// 声明一个变量但不分配内存
char *ptr;

// ptr=str表示分配内存并赋值(在全局区不允许)
ptr=str;

最后,再附一张C/C++的栈空间和堆空间示意图
图片说明

一般C语言可以在函数体外定义变量并初始化但不能在函数体外对变量单独进行赋值 这里更深的学问涉及到编译问题

简单来说c语言执行的对象是函数体,任何赋值、计算等操作都要放在具体的函数里才能执行。
放在函数外的全局变量只能是定义或声明或在定义的时候直接初始化掉。
char str[30] = "Hello world";
char *ptr = str;

以上两行是定义全局变量,char *ptr = str; 定义时直接初始化掉没有问题!
char str[30] = "Hello world";
char *ptr;
ptr = str;
以上代码问题就在 ptr = str;这一条语句在函数体外,可以理解成编译的时候无法确定该行代码由谁在何时去执行因此编译报错!

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^