方法1:定义一个char类型的二维数组
char str[4][20] = {"I love C","I love you","C语言","string"};
这种方法是通过定义一个char类型的二维数组实现,通过二维数组的行索引可得到数组中的每个字符串,列的大小限定了每个字符串所能包含的最大字符个数,所以采用这种定义方式时,列的大小必须不能小于数组所有字符串的最大长度;
在取该数组的每个字符串时,直接对行索引即可
方法2:定义一个指向char类型的指针数组
这种方法是通过定义一个指向char类型的指针数组实现,数组中的每个元素都是一个指针,通过该指针可得到数组中的每个字符串。如对于上面的数组,C语言的定义代码如下:
char *str[5] = { "I love C","I love you","C语言","string" };
比较
上面的两种方法都可以实现我们的目的,但在内存的占用上两种方法不同。第1种方法定义了一个5行20列的二维数组,即每个字符串所占的字节长度都为20个,所以共需要占用100个字节,而第2种方法是定义的指针数组,每个指针指向的字符串占用的字节长度是其实际长度,所以其总的长度肯定小于100个字节。综合来讲,第1种方法相对于第2种方法,造成了存储空间的浪费情况
一般在C语言中定义字符串的数组时,推荐使用第2种方法,特别是对于单片机、嵌入式等方面的程序开发时,可以充分利用有限的硬件资源,避免存储空间的浪费。
补充:char **a == char *a[] 可以叫做 指针数组
字符串1存在 0x0001~0x0008
字符串2存储在 0x0016~0x0032
但是我们可以定义一个char**变量,动态申请两个char地址的内存,用于存放字符串1的首地址0x0001 和字符串2的首地址0x0016
或者定义char a[2]来存放这两个字符串的首地址
a[0] = 0x0001
a[1] =0x0016
char *str[2]= {"1地址“,”2地址“}; 这里可以存不连续的地址,但是str1[0 ] str[1] 地址连续,数组连续申请