数组与指针区别的个人理解

在编程中我们经常会会用到数组与指针,也都知道可以通过指针来访问数组,那这二者又有什么区别呢?

我们来看下面的几个代码:
head.c

char *p = "abcdefg";

test.c

#include<stdio.h>
extern char *p;
int main()
{
    printf("%s\n", p);
    return 0;
}

这里写图片描述
我们创建了一个工程,将head.c和test.c 一起放入源文件中,在head.c中创建指针变量char *p = “abcdefg”,然后再在test.c中声明它,再通过%s的形式将其输出。这时屏幕上输出了abcdefg的值。
我们对代码做部分修改:
head.c

char *p = "abcdefg";

test.c

#include<stdio.h>
extern char p[];
int main()
{
    printf("%s\n", p);
    return 0;
}

这里写图片描述

在这我们可以看到,在head.c中,我们定义的变量为字符指针变量,而在test.c中我们将它声明为了字符数组,这时,再对p以%s输出,输出的值为随机值。那这是什么原因呢?

我们再对它做研究:
我们知道,对于head.c中的指针变量p,对它的初始化,并不是将”abcdefg”的值存入了p中,而是常量字符串中首元素‘a’的地址存储到了p中。对于test.c中声明的数组p来说,它是将head.c中的指针变量声明为了数组,由于它们是同一块空间,所以它是将指针p的值,也就是‘a’的地址,当成了值存到了数组中,因此我们在这里输出的就是‘a’的地址,我们可以对它做进一步的验证。
这里写图片描述
我们将test.c中p数组的每个元素以16进制输出,然后再重新定义一个指针指向常量字符串“abcdefg”(相同的常量字符串在一个程序中,只存在一份,所以地址相同),由于此电脑存储为小端存储,因此将两个输出对比,我们可以看p中存储的正是常量字符串的首地址,也就是‘a’的地址。图解如下:
这里写图片描述
那如果我们已经将p指针声明成了p数组,我们怎么保证它输出的正确性呢?我们看下面的代码:
这里写图片描述
以%s格式输出,我们需要给到abcdefg的地址,而现在p[]数组的值就是字符串的地址,因此我们只需要一次将数组的所有内容读出即可,我们知道p(数组名)的值也代表了首元素的地址,因此,我们将p强制类型转换为char**,这样p中的值就可以被以地址的形式一次全部访问到,我们再对其解引用,就得到了a的地址,这时我们就可以得到想要得到的值,同时,这也印证了我们前面的分析。

那如果在head.c中将其定义为数组,在test.c中将其声明为指针呢?指针大小为4个字节,所以我们将字符串改为4个字节(包括’/0’,所以为’abc’)。

head.c

char p[] = "abc";

test.c

#include<stdio.h>
extern char *p;
int main()
{
    printf("%s\n", p);
    return 0;
}

这里写图片描述
用与前面一样的分析方法,我们可以得出结论,当前p中存储的并不是”abc”的地址而是”abc“的值。我们可以以16进制输出p,看到p的值具体是多少:
这里写图片描述
我们对其做以图解:
这里写图片描述
现在,我们要以%s格式输出“abc”,我们只需要拿到a的地址,就可以将其输出,而p的值正是“abc”,所以这次我们要输出的值为p,而不是p指向的空间的值,因此,我们只要拿到p的地址,将其强转为char*类型,那么以%s形式输出就得到了我们需要的值。
这里写图片描述

以上就是我对数组与指针定义以及声明问题的个人理解,不足之处还望指正。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值