数组与指针的定义与声明

在这里我们主要来分析两种情况:

1.定义为数组声明成指针。

首先我们来闯将两个源文件sum.c和test.c
然后在sum.c中我们写这个代码只定义数组并且给它赋值。

char str[] = "abcdef";

test.c中我们用来声明成指针

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
extern *str;
int main()
{
    printf("%s\n", str);
    system("pause");
    return 0;
}

按照我们的理解,数组名是首元素地址,按理来说我们应该可以正常输出“abcdef”
然而并不然我们来看看结果:
这里写图片描述
哎呦,程序挂掉了。看来情况并不是像我们所想的那样啊。那程序是怎么挂掉的?
我们来分析分析:
首先我们要知道声明和定义的时候指的是一块空间,我们sum.c中定义数组放在一块空间里,
然后在test.c中不管声明成指针还是数组仍然指的是这一块空间,
我么你在这里把str声明成指针的时候,指针大小是几个字节?4个字节,而指针str又是这块空间,所以我们一定能拿到的是前四个字符abcd,不信?我们来试试

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
extern *str;
int main()
{
    printf("%x\n", str);
    system("pause");
    return 0;
}

会输出什么呢?
这里写图片描述
输出了64636261也许你还是没有发现什么
但这样哪64 63 62 61 这不就是dcba的十六进制吗?
最开始我们一位存放的是数组首元素地址,用%s输出,现在我们知道str指针中存放的是这么一串东西?你说编辑器能给你找到64636261这个地址的位置吗?
这里写图片描述
说到这 你说我们就非得给它定义成数组,声明成指针还像把它正确输出出来有什么办法呢?
我们要用%s输出肯定得找到a的地址,我们我们刚知道str中存放的是64 63 62 61相当于dcba,
那我们如果对str取地址不就相当于对这块空间的abcd进行取地址了吗?然后再找到它首元素的地址,将&str强制类型转换为char*类型,我们知道char*指向一个字节,这样就可以找到a的地址不就可以解决问题了吗

int main()
{
    printf("%s\n", (char *)&str);
    system("pause");
    return 0;
}

这里我们就可以看到数组和指针的不一样,指针无论何时大小都是四个字节,而数组却不一定。

2.定义成指针声明成数组。

同样的两个源文件
sum.c中

#define _CRT_SECURE_NO_WARNINGS 1
char *str = "abcdef";

test.c中

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
extern str[];
int main()
{
    printf("%s\n", str);
    system("pause");
    return 0;
}

运行结果:
这里写图片描述
这里输出的是乱码怎么回事呢?我们再来分析分析
其实主要我们要请除指针和数组中存放的是什么,定义与声明指向的是同一块空间,这里定义的是指针,而我们声明成数组,但数组里其实存放的应该是指针变量str的内容而不是字符串也就是首元素的地址,同时指针只开辟了四个字节,所以这里的数组大小肯定也是四个字节,这时我们能用%s输出来当然会输出乱码,因为数组里本来就存放的地址而不是字符串。

如果我们就非得输出来abcdef该怎么办呢?
首先我们知道了str数组中存放的指针变量str的内容,而str的内容就是字符串abcdef的地址,所以我们只需要把它的内容取出来就行了,我们知道指针大小是四个字节,要取出str[]数组的内容,同时我们知道int变量也是所以我们可以先将str强制类型转换成int 然后在解引用,引用出来存放的四个字节,就是字符串的地址,然后再强制类型转换为char 类型,再用%s输出。这样应该是可以输出的。
这里写图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
extern str[];
int main()
{
    printf("%s\n",(char *)*(int *)str);
    system("pause");
    return 0;
}

其还可以用指针数组的形式
声明成*str[];
然后输出的时候直接解引用str这样也是可以输出的。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值