1、指针数组
2、赋值
1、指针数组
const char *g_sHelpCommSet[][2]={{"1","2323"},{"3","4dfdsfd"}};
对于这个数组来看看系统给它分配的内存空间是什么样子的?!
写个address.c
#include <stdio.h>
const char *g_sHelpCommSet[][2]={{"1","2323"},{"3","4dfdsfd"}};
int main( void ) { return 0; }; |
编译,带-g参数,方便在gdb中调试
$ gcc -g -o test test.c |
然后调试,查看内存,系统是怎么给g_sHelpCommSet安排内存的
$ gdb address GNU gdb 6.6-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-gnu"... Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". /* 在程序入口处设制断点 */ (gdb) break main Breakpoint 1 at 0x8048352: file address.c, line 7. /* 运行程序 */ (gdb) run Starting program: /home/guaicat/workroom/memory/address
Breakpoint 1, main () at address.c:7 7 return 0; (gdb) /* 看g_sHelpCommSet 数组在内存中的模样 */ (gdb) x/12x g_sHelpCommSet 0x804954c <g_sHelpCommSet>: 0x0804842c 0x0804842e 0x08048433 0x08048435 0x804955c <completed.5758>: 0x00000000 0x00000000 0x00000000 0x00000000 0x804956c: 0x00000000 0x00000000 0x00000000 0x00000000 /* 注意:g_sHelpCommSet是0x804954c, 0x0804842c是数组里面的值 */ /* 继续看,g_sHelpCommSet 指向的内存单元 */ (gdb) x/24b 0x0804842c 0x804842c: 0x31 0x00 0x32 0x33 0x32 0x33 0x00 0x33 0x8048434: 0x00 0x34 0x64 0x66 0x64 0x73 0x66 0x64 0x804843c: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 |
对于系统或者程序来说,因为char *指针类型,所以它认识的g_sHelpCommSet 仅仅是一个指针, 0x804954c;记住了,g_sHelpCommSet就是 0x804954c,而且仅仅是 0x804954c!!!
指针数组,对于系统或者程序来说,依然是一个指针,但是因为数组的下标,程序会为这个指针数组设制偏移量来解释,比如申明的g_sHelpCommSet[][2]中,g_sHelpCommSet[i][j]就被解释为 g_sHelpCommSet + (sizeof(char*)*2)*i + (sizeof(char*))*j 的地址,因为sizeof(char *)==4,所以
g_sHelpCommSet[0][0] = 0x804954c + (4*2)*0 + (4)*0 = 0x804954c g_sHelpCommSet[0][1] = 0x804954c + (4*2)*0 + (4)*1 = 0x8049550 g_sHelpCommSet[1][0] = 0x804954c + (4*2)*1 + (4)*0 = 0x8049554 g_sHelpCommSet[1][1] = 0x804954c + (4*2)*1 + (4)*1 = 0x8049558 |
因为数组记录的是首地址,靠下标来算偏移量来决定某个数组成员的实际内存地址,这跟指针里面的地址操作是一样的,所以,表达一个数组char array[7]的成员,可以用array[3]这种方式,也可以用(array+3)来表达,它们都是array的地址+sizeof(char)*3的那个内存单元:)
我们知道这个指针数组了,再看看指针数组每个指向的内存单元内容
(gdb) x/12x g_sHelpCommSet 0x804954c <g_sHelpCommSet>: 0x0804842c 0x0804842e 0x08048433 0x08048435 0x804955c <completed.5758>: 0x00000000 0x00000000 0x00000000 0x00000000 0x804956c: 0x00000000 0x00000000 0x00000000 0x00000000 |
可以看出来:
g_sHelpCommSet[0][0],即0x804954c里面存着 0x0804842c
g_sHelpCommSet[0][1],即0x8049550里面存着 0x0804842e
g_sHelpCommSet[1][0],即0x8049554里面存着 0x08048433
g_sHelpCommSet[1][1],即0x8049558里面存着 0x08048435
这些又是什么呢?这些就是g_sHelpCommSet成员所表达的字符串的首地址
(gdb) x/24b 0x0804842c 0x804842c: 0x31 0x00 0x32 0x33 0x32 0x33 0x00 0x33 /* '1' '\0' '2' '3' '2' '3' '\0' '3' */ 0x8048434: 0x00 0x34 0x64 0x66 0x64 0x73 0x66 0x64 /* '\0' '4' 'd' 'f' 'd' 's' 'f' 'd' */ 0x804843c: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 /* '\0' */ |
0x0804842c指向的字符串是 0x31 0x00,即 “1”
0x0804842e指向的字符串是 0x32 0x33 0x32 0x33 0x00,即 ”2323”
0x08048433指向的字符串是 0x33 0x00,即 ”3”
0x08048435指向的字符串是 0x34 0x64 0x66 0x64 0x73 0x66 0x64 0 x00,即 ”4dfdsdf”
由此,我们可以总结出下图: