指针和数组

指针和数组是两个不同概念,比较容易产生混淆的原因是数组表示法其实是在变相的使用指针。
一个T数组类型的对象如果出现在表达式中会退化为一个指向数组第一个元素的指针(有3种例外情况),指针的类型是指向T的指针。
一旦数组出现在表达式中,编译器会隐式地生成一个指向数组第一个元素的指针,就像是&a[0]一样,当数组作为sizeof或&操作符的操作数,或者作为字符数组的字符串初始值的时候例外。

/* a.c */
const char version[] = "V22030122";
/* b.c */
extern const char *version;
int main(int argc, char *argv[])
{
    printf("%s\r\n", version);
    return 0;
}
程序执行结果是:
A 输出:V22030122
B 输出:V
C 输出乱码
D 程序异常退出

答案是D。
C语言没有专门用于存储字符串的变量类型,字符串常量不可修改,被保存在.rodata中,其起始地址可用于保存字符指针类型的变量中。
b.c中引入version时,申明的是一个字符指针,相比于数组,指针在访问相同数据时,会多一次内存寻址,如果是32-bit环境,前4个字节“V220”会被当做内存地址进行第2次寻址;如果是64-bit环境,“V2203012”会被当做内存地址。“V220”对应ASCII码0x56 0x32 0x32 0x30,若是小端环境,则会读取内存0x30303256,此处内存恰好能输出乱码可能性极小,大概率会发生core dump,段访问错误。
在这里插入图片描述
对于a和p是数组和指针,a[0`和p[0]这样的引用生成的代码差别很大。如下图:
当编译器看到表达式a[0]时,它生成的代码从a的位置开始跳过0个,然后取出哪个字符(对应下图汇编代码第二行)。当它看到p[0],生成代码会先找到p的位置取出其中的指针值,在指针值加0然后取出指向的字符(对应下图汇编第一三行)。
由此可见,a[0]是名为a的对象(的起始位置)之后第0个位置的值,而p[0]是p指向的对象的第0个位置的值。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值