[基础]关于extern指针和数组的用法

之前有在外面面试,遇到一题如下:

filea.c
char *p = "abcdefg";

fileb.c
extern char p[];
printf("p[0]=%d\n", p[0]);
result=?

当时只是纠结于printf中的%d打印char类型数据,会不会按地址将abcd这四个字节的数据打印出来,所以给出的答案是:0x61626364. 

类似的还有这种做法:

filea.c
char p[10];

fileb.c
extern char p[];
extern char *p;
p[0] = ?

上面这个char p[10], p只是个别名,下面的extern char *p提取p的地址可能是0,然后对p[0]赋值可能导致程序崩溃。

之后,回来查了些资料,写了个代码试了下:

filea.c

char *str = "abcdefg";

 

fileb.c

#include "stdio.h"

extern char str[];
char *str2 = "abcdef";


void main(void)
{
    int i = 0;
    
    printf("str1:addr=0x%08x, %d, %d, %d\n", (unsigned int)str, str[0], str[1], str[2]);
    
    printf("str2\n");
    for(i = 0; i < sizeof(str2); i++)
    {
        printf("[%d]=%c ", i, str2[i]);
    }
}

 

 Makefile

objects = filea.o fileb.o
hello:$(objects)
    gcc -o hello $(objects)
filea.o: filea.c
fileb.o: fileb.c
clean:
    rm hello $(objects)

 

Result:

str:addr=0x00601048, -52, 6, 64
str2
[0]=a [1]=b [2]=c [3]=d [4]=e [5]=f [6]= [7]=s %

 

可以看出str的输出并不是我们想要的。

为什么呢?

首先,关于指针和数组名

  • 系统会为“指针名”分配4个字节的内存空间。存放指针的内存空间和该内存中存放的数据,前者为存放指针的地址,后者为存放有效数据(如abcdef)的地址。
  • 而数组名则不会,数组名只是一块存放数据地址空间的别名。

其次,由于在fileb.c中extern char str[]; str被申明为数组,那么str就是代表一块地址空间的别名,也就是存放str指针地址空间的别名,而不是上面说道的有效数据的地址空间,所以str[0]只是存放abcdef地址空间的值。

 

结论:使用声明和定义要匹配。

转载于:https://www.cnblogs.com/aaronLinux/p/6390511.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值