字符串可以用作数组索引吗?

字符串可以用作C中的数组索引吗?

例如:字符串对应值“ONE”1“TWO”2“五”5“十”10

当上面列表中的字符串传递给函数时,该函数必须返回上面指示的相应值。 可以通过声明一个以字符串作为索引的常量数组来实现

int *x; x["ONE"] = 1; x["TWO"] = 2; x["FIVE"] = 5; x["TEN"] = 5; return x["string received by the function"]; 

上述逻辑不能按预期工作; 是否有一个解决方法来实现上述逻辑,以便有一个字符串索引数组?

它可能会编译,但它不起作用。

你想要实现的目标并不完全清楚。 我想你想要一个关联数组 ,在这种情况下你应该找到一个库实现。

如果您正在寻找更像枚举类型的东西,并且您可以依赖C89 ,请查看以下内容:

 enum cardsuit { CLUBS, DIAMONDS, HEARTS, SPADES }; 

如果你不能依赖C89,那么你应该尝试一些typedef技巧。

对于你应该做的事情还有其他很好的答案,所以我想我会解释你在做什么以及为什么它正在编译而不能正常工作。

在C中,通过使用数组或指针以及某种整数来完成数组引用。 (在x [1]中,x是数组,1是整数)。 只要您使用某种整体类型,它就会像您期望的那样工作。

假设你有一些不是整数的东西。 在这种情况下,C实现将查看它是否可以将其转换为适当的类型,因此您最终得到数组和整数。 在这种情况下,你遇到了麻烦(在C ++中略微更复杂的版本使得经验丰富的人混淆了你)。

在C中,像“one”这样的文字字符串是const char *类型,意味着指向您无法更改的字符。 实际值是字符串实际驻留在内存中的内存地址。 通常情况下,你不会注意这个指针值,看看字符串值,但这里有一个问题。

在C中,任何数据指针都可以转换为某种整数,并且将自动转换。 因此,你有一个像“one”这样的字符串,它的值是代表内存地址的任何数字。 在C期望某种整数的情况下使用它,它将被转换为某个整数值或其他值。

因此,这就是x [“ONE”]正在发生的事情。 C系统必须将字符串“ONE”放在内存中的某个位置,并不重要。 它很可能是一个内存相当大的地方,很可能是数十亿。 当它看到x [“ONE”]时,它会尝试将该值转换为整数,并将其用作下标。 因此,您尝试远远超出其范围访问数组x,这导致了问题。 你要么试图使用你不允许使用的内存,而系统只是阻止你,或者你正在捣乱你应该独自留下的大块内存,而且以后可能会以某种神秘的方式失败。

您将需要编写一个将字符串映射到整数的函数,或者使用整个枚举(然后可能是一个将枚举值映射到字符串的函数)。

通常,后者更好:传递整数,因此实现不依赖于可能在表示中使用的字符串的细节。 例如,考虑一下如何管理本地化(翻译),如果你需要让某些人说出不同的语言,这些字符串是可口的。

您可以使用stdlib.h提供的函数bsearch()轻松构建查找表。 一个工作的例子是这样的:

 #include  #include  #include  #define count(ARRAY) (sizeof(ARRAY)/sizeof(*ARRAY)) struct item { const char * name; int value; }; static _Bool sorted; static struct item items[] = { { "one", 1 }, { "two", 2 }, { "three", 3 }, { "ten", 10 } }; static int compare(const void * p1, const void * p2) { return strcmp(*((const char **)p1), *((const char **)p2)); } int get(const char * name) { if(!sorted) { qsort(items, count(items), sizeof(*items), compare); sorted = 1; } struct item * item = bsearch(&name, items, count(items), sizeof(*items), compare); return item ? item->value : 0; } int main(int argc, char ** argv) { int i; for(i = 1; i < argc; ++i) printf("%i\n", get(argv[i])); return 0; } 

您正在寻找的可能相当于一个关联数组,在C中不能提供相同的语法糖,但是没有一些愚蠢的结果。

但是,如果您的数据符合键 – >值对,则可以提供的是散列映射。 您需要的是适当的哈希函数。

这里有一个很好的简单哈希表示例:

http://www.cl.cam.ac.uk/~cwc22/hashtable/

如前所述,您需要一个关联数组或哈希映射或等效的。 这种代码的一个可能来源是Hanson的“ C接口和实现 ”( Google Code中的代码 – 在使用之前仔细检查许可条款等)。

这是一个旧线程,但我认为这对于那些寻找实现的人来说可能仍然有用。 它不需要太多代码; Hank Gay建议我在没有任何额外库的情况下做了大约100行。 我把它称为字典,因为它与python数据类型相似(有点)。 这是代码:

 #include  #include  #include  typedef struct hollow_list hollow_list; struct hollow_list{ unsigned int size; void *value; bool *written; hollow_list *children; }; //Creates a hollow list and allocates all of the needed memory hollow_list hollow_list_create(unsigned int size){ hollow_list output; output = (hollow_list) {.size = size, .value = (void *) 0, .written = calloc(size, sizeof(bool)), .children = calloc(size, sizeof(hollow_list))}; return output; } //Frees all memory of associated with a hollow list and its children void hollow_list_free(hollow_list *l, bool free_values){ int i; for(i = 0; i < l->size; i++){ hollow_list_free(l->children + i, free_values); } if(free_values){ free(l->value); } free(l); } //Reads from the hollow list and returns a pointer to the item's data void *hollow_list_read(hollow_list *l, unsigned int index){ if(index == 0){ return l->value; } unsigned int bit_checker; bit_checker = 1<<(l->size - 1); int i; for(i = 0; i < l->size; i++){ if(bit_checker & index){ if(l->written[i] == true){ return hollow_list_read(l->children + i, bit_checker ^ index); } else { return (void *) 0; } } bit_checker >>= 1; } } //Writes to the hollow list, allocating memory only as it needs void hollow_list_write(hollow_list *l, unsigned int index, void *value){ if(index == 0){ l->value = value; } else { unsigned int bit_checker; bit_checker = 1<<(l->size - 1); int i; for(i = 0; i < l->size; i++){ if(bit_checker & index){ if(!l->written[i]){ l->children[i] = hollow_list_create(l->size - i - 1); l->written[i] = true; } hollow_list_write(l->children + i, bit_checker ^ index, value); break; } bit_checker >>= 1; } } } typedef struct dictionary dictionary; struct dictionary{ void *value; hollow_list *child; }; dictionary dictionary_create(){ dictionary output; output.child = malloc(sizeof(hollow_list)); *output.child = hollow_list_create(8); output.value = (void *) 0; return output; } void dictionary_write(dictionary *dict, char *index, unsigned int strlen, void *value){ void *hollow_list_value; dictionary *new_dict; int i; for(i = 0; i < strlen; i++){ hollow_list_value = hollow_list_read(dict->child, (int) index[i]); if(hollow_list_value == (void *) 0){ new_dict = malloc(sizeof(dictionary)); *new_dict = dictionary_create(); hollow_list_write(dict->child, (int) index[i], new_dict); dict = new_dict; } else { dict = (dictionary *) hollow_list_value; } } dict->value = value; } void *dictionary_read(dictionary *dict, char *index, unsigned int strlen){ void *hollow_list_value; dictionary *new_dict; int i; for(i = 0; i < strlen; i++){ hollow_list_value = hollow_list_read(dict->child, (int) index[i]); if(hollow_list_value == (void *) 0){ return hollow_list_value; } else { dict = (dictionary *) hollow_list_value; } } return dict->value; } int main(){ char index0[] = "hello, this is a test"; char index1[] = "hello, this is also a test"; char index2[] = "hello world"; char index3[] = "hi there!"; char index4[] = "this is something"; char index5[] = "hi there"; int item0 = 0; int item1 = 1; int item2 = 2; int item3 = 3; int item4 = 4; dictionary d; d = dictionary_create(); dictionary_write(&d, index0, 21, &item0); dictionary_write(&d, index1, 26, &item1); dictionary_write(&d, index2, 11, &item2); dictionary_write(&d, index3, 13, &item3); dictionary_write(&d, index4, 17, &item4); printf("%d\n", *((int *) dictionary_read(&d, index0, 21))); printf("%d\n", *((int *) dictionary_read(&d, index1, 26))); printf("%d\n", *((int *) dictionary_read(&d, index2, 11))); printf("%d\n", *((int *) dictionary_read(&d, index3, 13))); printf("%d\n", *((int *) dictionary_read(&d, index4, 17))); printf("%d\n", ((int) dictionary_read(&d, index5, 8))); } 

不幸的是你无法复制list [x]语法,但这是我提出的最佳选择。

在“普通C”中,你可以模仿使用字符串作为索引,但不能像你想要的那样使用QUITE。 但是,这样做很少有用,而且大多数都是使代码不可读的好方法。 您似乎想要的是能够将字符串键用于字典(或“散列表”,如果您愿意)并且C中没有内置数据结构。确切的设计将取决于您的内容想要(事实上,如果这是家庭作业的一部分,你可能甚至不需要使用完整的哈希表实现,但可能会使用性能较低的静态编码)。

在a [b]构造的“索引位置”中使用字符串(OK,char数组)的示例:

 int main (void) { char *str = "This is a test string"; int x; for (x=0; x < 12; x += 3) putchar(x[str]); printf("\n"); return 0; } 

据我所知,上面是合法的C,具有明确定义的输出(字符串“Tss ssi”)。 它依赖于a [b]被定义为与*(a + b)相同的事实。