在ANSI C中,在一个一维数组中可以有多个字符串吗?
我知道如何使用二维数组创建字符串数组,但我可以这样做:在ANSI C中,在一个一维数组中可以有多个字符串吗?,c,arrays,string,ansi-c,C,Arrays,String,Ansi C,我知道如何使用二维数组创建字符串数组,但我可以这样做: char array[]; array[1]="bob"; array[2]="cat"; 是的,但不是你想要的方式 例如,您可以这样做: char arr[] = "bob\0cat"; arr包含两个字符串,从arr[0]开始的“bob”和从arr[4]开始的“cat”。这不是特别方便,因为必须遍历数组才能找到字符串,但它确实有效地使用了内存 arr的每个元素都是单个char,因此不能在每个元素中存储字符串,但可以连续存储多个字符串
char array[];
array[1]="bob";
array[2]="cat";
是的,但不是你想要的方式 例如,您可以这样做:
char arr[] = "bob\0cat";
arr
包含两个字符串,从arr[0]
开始的“bob”和从arr[4]
开始的“cat”
。这不是特别方便,因为必须遍历数组才能找到字符串,但它确实有效地使用了内存
arr
的每个元素都是单个char
,因此不能在每个元素中存储字符串,但可以连续存储多个字符串
还有其他方法来存储字符串列表。最常见的方法是定义一个char*
指针数组,每个指针指向已分配到其他位置的字符串(第一个字符)。main
的argv
参数是这种方法最常见的例子
在您的示例中:
char array[];
这是无效的;如果要定义数组对象,必须指定元素数
array[1]="bob";
array[2]="cat";
这些赋值都是无效的array[1]
和array[2]
都是单个char
对象。不能将字符串分配给单个字符。实际上,表达式“bob”
被隐式转换为char*
指针——您仍然无法将其分配给char
对象
如果将数组
定义为char*
指针数组,则这些赋值将是有效的,事实上,这是表示字符串列表的常用方法:
char *array[2]; /* an array of pointers */
array[0] = "bob";
array[1] = "cat";
字符串本身被分配到数组外部;数组包含指向它们的指针。每个指针实际上都指向一个char
对象,但我们可以使用该指针访问整个字符串。是的,但不是您尝试的方式
例如,您可以这样做:
char arr[] = "bob\0cat";
arr
包含两个字符串,从arr[0]
开始的“bob”和从arr[4]
开始的“cat”
。这不是特别方便,因为必须遍历数组才能找到字符串,但它确实有效地使用了内存
arr
的每个元素都是单个char
,因此不能在每个元素中存储字符串,但可以连续存储多个字符串
还有其他方法来存储字符串列表。最常见的方法是定义一个char*
指针数组,每个指针指向已分配到其他位置的字符串(第一个字符)。main
的argv
参数是这种方法最常见的例子
在您的示例中:
char array[];
这是无效的;如果要定义数组对象,必须指定元素数
array[1]="bob";
array[2]="cat";
这些赋值都是无效的array[1]
和array[2]
都是单个char
对象。不能将字符串分配给单个字符。实际上,表达式“bob”
被隐式转换为char*
指针——您仍然无法将其分配给char
对象
如果将数组
定义为char*
指针数组,则这些赋值将是有效的,事实上,这是表示字符串列表的常用方法:
char *array[2]; /* an array of pointers */
array[0] = "bob";
array[1] = "cat";
字符串本身被分配到数组外部;数组包含指向它们的指针。每个指针实际上指向一个单独的char
对象,但我们可以使用该指针访问整个字符串。是的,只有当您能够将内存想象为一个原始的连续单元并确切地知道您在做什么时,才可能
比如说,
让我们考虑以下25个字节的内存块:
00 04
+----+----+----+----+----+
| | | | | |
+----+----+----+----+----+ 09
| | | | | |
+----+----+----+----+----+ 14
| | | | | |
+----+----+----+----+----+ 19
| | | | | |
+----+----+----+----+----+ 24
| | | | | |
+----+----+----+----+----+ 29
让我考虑一下我的分配是这样的
void *p = malloc( 5 * 5 * sizeof( char ) );
我可以使用纯指针算术访问大小为5的行,如下所示
例如,假设我将复制第三行中的字符串
memcpy ( p+(5*3) , "Hello", 5 );
唯一的问题是维护这个原始区域比通常要复杂一点,而且在使用上也有优势。是的,只有当您能够将内存想象成一个原始的连续单元,并且确切地知道您在做什么时,才有可能
比如说,
让我们考虑以下25个字节的内存块:
00 04
+----+----+----+----+----+
| | | | | |
+----+----+----+----+----+ 09
| | | | | |
+----+----+----+----+----+ 14
| | | | | |
+----+----+----+----+----+ 19
| | | | | |
+----+----+----+----+----+ 24
| | | | | |
+----+----+----+----+----+ 29
让我考虑一下我的分配是这样的
void *p = malloc( 5 * 5 * sizeof( char ) );
我可以使用纯指针算术访问大小为5的行,如下所示
例如,假设我将复制第三行中的字符串
memcpy ( p+(5*3) , "Hello", 5 );
唯一的问题是,维护这个原始区域比通常要复杂一点,而且在使用上也有一些优势。如果您谈论的是存储指向字符串的指针,那么是的:
const char *strings[SIZE];
strings[0] = "bob";
strings[1] = "cat";
...
注意,我们只在字符串数组中存储字符串文本“bob”
和“cat”
的地址;字符串文本的内容存储在其他地方
strings
被声明为const char*
的数组,因为试图修改字符串文本的内容会导致未定义的行为
如果要在单个一维数组中存储多个字符串的内容,则需要将它们连接在一起,如:
char dest[SIZE] = {0}; // want to make sure at least the first element is 0
strcat( dest, "bob" );
strcat( dest, "cat" );
之后的dest
包含字符串“bobcat”
,其中“bob”
从索引0开始,而“cat”
从索引3开始。请注意,不能使用=
运算符分配字符串内容;您必须使用库函数,如strcat
,或者必须单独分配每个字符,如
dest[0] = 'b';
dest[1] = 'o';
dest[2] = 'b';
...
如果要跟踪单个字符串在该一维序列中的起始和结束位置,则需要添加某种分隔符,如
strcat( dest, "bob" );
strcat( dest, "$" );
strcat( dest, "cat" );
给你字符串“bob$cat”
;然后可以使用strtok
或strchr
在字符串列表中查找单个字符串 如果你说的是ab