zoukankan      html  css  js  c++  java
  • [基础]关于extern指针和数组的用法

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

    filea.c
    char *p = "abcdefg";
    
    fileb.c
    extern char p[];
    printf("p[0]=%d
    ", 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
    ", (unsigned int)str, str[0], str[1], str[2]);
        
        printf("str2
    ");
        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地址空间的值。

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

  • 相关阅读:
    MYSQL ALTER
    初入园子
    java常用基础(一)
    C语言类型转换
    C++用EGE简单实现别踩白块游戏
    CPP常用库函数以及STL
    至我的新博客
    工厂模式
    pl/sql developer 编码格式设置
    单例模式
  • 原文地址:https://www.cnblogs.com/aaronLinux/p/6390511.html
Copyright © 2011-2022 走看看