C/C++ char數組存儲字符串內存地址組織方式


問題描述:

 1 #include <stdio.h>
 2 
 3 int main(void)
 4 {
 5     //program 6.3 Arrays of strings
 6     char str2[3][10];
 7     
 8     for(int i=0;i<3;++i){
 9         for(int j = 0;j<10;j++){
10             str2[i][j]='a';
11             //printf("%p ", &str2[i][j]);
12         }
13         //printf("\n");
14     }
15     
16     for(int i=0;i<3;++i){
17         for(int j = 0;j<12;j++){     //  索引 j->1218             printf("%c",str2[i][j] );  
19             //printf("%p  ",&str2[i][j]);
20         }
21         printf("\n");
22     }
23     return 0;
24 }

運行結果:

aaaaaaaaaaaa
aaaaaaaaaaaa
aaaaaaaaaaNULNUL

顯然代碼第18行數組索引越界(java:IndexOutOfBoundsException),但程序編譯運行通過,且越界索引對應的數組值補為a和NULL。

 


 

                                                    
如上圖所示, &numbers[1][0] = &number[0][4] + sizeof(number) / strnlen_s( number, sizeof(str));
即number[1][0]的地址等於number[0][4]的地址加上數組number的類型所占字節數(如int占4字節)。

 


 

通過打印數組每個元素地址觀察得出原因

 1 #include <stdio.h>
 2 
 3 int main(void)
 4 {
 5     //program 6.3 Arrays of strings
 6     char str2[3][10];
 7     
 8     for(int i=0;i<3;++i){
 9         for(int j = 0;j<10;j++){
10             str2[i][j]='a';
11         }
12     }
13 
14     for(int i=0;i<3;++i){
15         for(int j = 0;j<12;j++){
16             printf("%c",str2[i][j] );
17             printf("%p  ",&str2[i][j]);
18         }
19         printf("\n");
20     }
21     return 0;
22 }

 運行結果:

a0x7ffee509c710  a0x7ffee509c711  a0x7ffee509c712  a0x7ffee509c713  a0x7ffee509c714  a0x7ffee509c715  a0x7ffee509c716  a0x7ffee509c717  a0x7ffee509c718  a0x7ffee509c719  a0x7ffee509c71a  a0x7ffee509c71b  
a0x7ffee509c71a  a0x7ffee509c71b  a0x7ffee509c71c  a0x7ffee509c71d  a0x7ffee509c71e  a0x7ffee509c71f  a0x7ffee509c720  a0x7ffee509c721  a0x7ffee509c722  a0x7ffee509c723  a0x7ffee509c724  a0x7ffee509c725  
a0x7ffee509c724  a0x7ffee509c725  a0x7ffee509c726  a0x7ffee509c727  a0x7ffee509c728  a0x7ffee509c729  a0x7ffee509c72a  a0x7ffee509c72b  a0x7ffee509c72c  a0x7ffee509c72d  NUL0x7ffee509c72e   NUL0x7ffee509c72f

 

 注意標注的兩組彩色地址,想象中出現越界的str2[0][10]、str2[0][11]與str2[1][0]、str2[1][1]地址是一致的,故越界索引的數組值為a。即str2[0][10]==str2[1][0],str2[0][11]==str2[1][1]。

 


 

延伸

1     char str1[][10] = {"AAAAAAAAAA","BBBBBBBBB","CCCCCCCCCC","DDDDDDDDD"};   //10個A
2     char str2[][10] = {"AAAAAAAAAA","BBBBBBBBB","CCCCCCCCC","SSS"};      //9個A

編譯報錯     str1:initializer-string for array of chars is too long

C中的字符串總是由\0字符結束,所以字符串的長度永遠比字符串中的字符數多1.

 

1   unsigned int count = 0;
2   while (str1[count])
3       ++count;

 '\0'字符的ASCII碼是0,對應於布爾值false。其他ASCII碼都不是0,對應布爾值true。因此,只要str1[count]不是'\0',循環就繼續執行。

 

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5 
 6     //program 6.3 Arrays of strings
 7     //char str[][10] = {"AAAAAAAAAA","BBBBBBBBB","CCCCCCCCC","DDDDDDDDD"};
 8     //char str2[][10] = {"AAAAAAA","BBBBBBBB","CCCCCCCC","SSS"};
 9     char str2[3][10];
10     
11     for(int i=0;i<3;++i){
12         for(int j = 0;j<10;j++){
13             str2[i][j]='a';
14             //printf("%p ", &str2[i][j]);
15         }
16         //printf("\n");
17     }
18 
19     for(int i=0;i<3;++i){
20         for(int j = 0;j<10;j++){
21             printf("%c",str2[i][j] );
22             //printf("%p  ",&str2[i][j]);
23         }
24         printf("\n");
25     }
26     
27     return 0;
28 }

 

輸出結果:

1. aaaaaaaaaa
2. aaaaaaaaaa 3. aaaaaaaaaa

本文一開始使用測試程序使用for循環對數組對應索引進行賦值則沒有使用'\0'做為結束標志,三個字符串間沒有分隔標志,可以說它們並不是字符串而是單一的字符。

 

 

 


 

 

由於本人剛入門,文中不免有這樣或者那樣的錯誤,希望各位朋友們不吝賜教指正。

最后由於考研時間原因,列出此程序小弟還有的一處疑惑

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     char str2[3][10];
 6     
 7     for(int i=0;i<3;++i){
 8         for(int j = 0;j<10;j++){
 9             str2[i][j]='a';
10         }
11     }
12 
13     for(int i=0;i<3;++i){
14         for(int j = 0;j<15;j++){
15             printf("%c",str2[i][j] );
16             //printf("%p  ",&str2[i][j]);
17         }
18         printf("\n");
19     }
20     return 0;
21 }

運行結果:

aaaaaaaaaaaaaaa
aaaaaaaaaaaaaaa
aaaaaaaaaaNULNUL`QR

 

紅色標記的字符經多次編譯發現其字符會變動

再次編譯結果:

aaaaaaaaaaaaaaa
aaaaaaaaaaaaaaa
aaaaaaaaaaNULNULDLEȜ

 


免責聲明!

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



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