写代码的篮球球痴 嵌入式Linux 2020-03-09

导语

在这里我们做种强调的是在两个文件中,定义为数组声明为指针和定义为指声明为数组的这辆中情况。那么我们就需要两个源文件test.c和main.c。

定义为数组,声明为指针

test.c

char arr[] = "abcdef";

main.c

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>

extern char *arr;   //声明

int main()
{
   printf("%s\n", arr);
   system("pause");
   return 0;
}

就会出现以下的错误:

声明为数组定义为指针,声明为指针定义为数组_嵌入式就会出现,读取位置发生访问冲突

  • 首先我们需要知道的是定义和声明使用的是同一块空间,我们在test.c中定义为数组,在main.c中使用,不管声明为数组还是指针都是用的是这一块空间。这里将声明的arr当为指针取出来的是四个字节的值,然后在打印字符串时,就会将这四个字节的值作为一个地址去寻找,我们可以先来看看代码呈现。声明为数组定义为指针,声明为指针定义为数组_嵌入式_02

我们会发现“64636261”不是dcba的ASSCII码吗?

所以我们就知道了它为何地址访问出错。看下图:声明为数组定义为指针,声明为指针定义为数组_嵌入式_03这里指针去访问了四个字节的空间,然后取出了dcba,将dcba当做地址码去取出字符,造成地址访问出错。那我们如何在定义为数组、声明为指针的情况下,取出数组中所存的字符串?

  • 要取出字符串,就必须知道首元素’a’的地址,上述的描述,不就让我们知道了arr中存放的就是64636261相当于dcba,我们对arr取地址就相当于取到了abcd的地址,我们在对这个地址强制转换为char*类型,不就取到了一个字节’a’的地址。字符串知道了首元素地址,打印就很方便啦!

main.c

#include <stdio.h>

extern char *arr;

int main()
{
   //printf("%s\n", arr);
   printf("%s\n", (char*)&arr);
   system("pause");
   return 0;
}
声明为数组定义为指针,声明为指针定义为数组_嵌入式_04定义为指针,声明为数组

test.c

char *p = "abcdef";

main.c

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdlib.h>
#include <stdio.h>

extern char arr[];  //这里只是说他是一个数组,不需要填写数组个数

int main()
{
   printf("%s\n", p);
   system("pause");
   return 0;
}

运行之后就会发现,呀!我的程序运行出来是随机值,不对呀,我明明将它存放进去了。

  • 首先我们就得清楚这个数组里面存放的是什么?
  • 定义为指针,然后指向了字符串”abcdef”,这里指针里面就存的是字符串首元素的地址
  • 声明为数组,定义为指针,大小只有四个字节,所以数组的大小也只有四个字节
  • 指针中存放的是字符串首元素的地址,数组中存放的是字符串首元素的地址,所以打印出来就是乱码了。

图解如下图所示:声明为数组定义为指针,声明为指针定义为数组_嵌入式_05那我们如何在定义为指针、声明为数组的情况下,取出指针中所指向的字符串?

  • 我们要找到字符串,就要将指针所存放的四个字节一次取出来,因为字符数组一次只能读一个字节,* 所以,我们需要把它强转为int*
  • 取出后,我们需要知道它里面的内容,就必须把它解引用,取出四个字节的地址,(int )p
  • 最后,我们要找到’a’的地址,就必须强转为char*,才能取出’a’的地址。main.c
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdlib.h>
#include <stdio.h>

extern char p[];    //这里只是说他是一个数组,不需要填写数组个数

int main()
{
   printf("%s\n", (char*)*(int*)p);
   system("pause");
   return 0;
}
声明为数组定义为指针,声明为指针定义为数组_嵌入式_06总结:
  1. 定义和声明使用的是同一块空间
  2. 指针大小是4个字节,数组大小不一定
  3. 指针和数组不一样

转自:https://blog.csdn.net/meng_lemon/article/details/80642938