C/C++ char数组存储字符串内存地址组织方式

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Ȝ

猜你喜欢

转载自blog.csdn.net/lusic01/article/details/88736683