[基礎]關於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地址空間的值。

 

結論:使用聲明和定義要匹配。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM