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

发布于 2024-07-10 12:24:50 字数 346 浏览 6 评论 0原文

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

前任: String 对应值 “一”1 “二”2 “五”5 "TEN" 10

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

int *x;
x["ONE"]  = 1;
x["TWO"]  = 2;
x["FIVE"] = 5;
x["TEN"]  = 5;

return x["string received by the function"];

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

Can a string be used as array index in C?

Ex:
String Corresponding value
"ONE" 1
"TWO" 2
"FIVE" 5
"TEN" 10

When a string in the above list is passed to the function, the function must return the corresponding value indicated above. Can this be achieved by declaring a constant array with string as index

int *x;
x["ONE"]  = 1;
x["TWO"]  = 2;
x["FIVE"] = 5;
x["TEN"]  = 5;

return x["string received by the function"];

The above logic does not work as expected; is there a workaround to implement the above logic in order to have a string-indexed array?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

沙沙粒小 2024-07-17 12:24:50

它可能会编译,但不会工作。

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

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

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

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

It might compile, but it won't work.

It's not entirely clear what you're trying to achieve. I think you want an associative array, in which case you should find a library implementation of one.

If you're looking for something more like an enumerated type, and you can rely on C89, look at something like:

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

If you can't rely on C89, then you should try some typedef trickery.

新人笑 2024-07-17 12:24:50

对于你应该做什么还有其他很好的答案,所以我想我应该解释一下你在做什么以及为什么它编译但不起作用。

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

假设你有一些不是整数的东西。 在这种情况下,C 实现将查看是否可以将其转换为适当的类型,因此最终会得到数组和整数。 在这种情况下,您会遇到麻烦(C++ 中稍微复杂的版本已经让比您更有经验的人感到困惑)。

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

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

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

There are other excellent answers to what you should do, so I thought I'd explain what you are doing and why it's compiling and not working.

In C, array reference is done by having an array or pointer and an integer of some sort. (in x[1], x is the array and 1 is the integer). As long as you're using some integral type, it'll work as you expect.

Suppose you have something that's not an integer. In that case, the C implementation will see if it can convert it to the appropriate type, so you wind up with array and integer. It's cases like this where you get into trouble (and slightly more sophisticated versions of this in C++ have confused more experienced people than you).

In C, a literal string like "one" is of type const char *, meaning pointer to characters you can't change. The actual value is the memory address of where the string actually resides in memory. Normally, you'd pay no attention to this pointer value, and look at the string value, but there's a gotcha here.

In C, any data pointer can be converted to some sort of integer, and will be automatically. Therefore, you've got a string like "one", and its value is whatever number that represents the memory address. Use it where C expects some sort of integer, and it'll get converted to some integral value or other.

Therefore, this is what's happening with x["ONE"]. The C system has to put the string "ONE" somewhere in memory, and it doesn't matter where. It's likely to be somewhere with a fairly large memory address, quite possibly in the billions. When it sees x["ONE"], it tries to convert that value to an integer, and uses it as a subscript. Therefore, you're trying to access the array x far, far beyond its bounds, and that's causing the problem. Either you're trying to use memory you're not allowed to, and the system just stops you, or you're mucking with a chunk of memory you should be leaving alone, and it's likely to fail in some mysterious way later.

紫轩蝶泪 2024-07-17 12:24:50

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

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#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;
}

You can easily build lookup tables with the function bsearch() provided by stdlib.h. A working example is this:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#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;
}
各自安好 2024-07-17 12:24:50

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

一般来说,后者更好:传递整数,以便实现不依赖于表示中可能使用的字符串的详细信息。 例如,如果您需要使这些字符串适合说不同语言的人,请考虑如何管理本地化(翻译)。

You will need to write a function that maps strings to integers, or alternatively use enumerations throughout (and then perhaps a function that maps enumerated values to strings).

In general, it's nicer to do the latter: to pass integers, so that the implementation isn't dependent on the details of strings that might be used in the representation. For example, think about how you would manage localization (translation) if ever you need to make those strings palatable to somebody speaking a different language.

洋洋洒洒 2024-07-17 12:24:50

您正在寻找的可能相当于一个关联数组,不幸的是,它无法在 C 中提供相同的语法糖,而不会产生一些愚蠢的结果。

但是,如果您的数据符合 key -> ,您可以提供的是哈希图。 值对。 您需要的是一个适当的哈希函数。

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

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

What you are looking for is probably the equivalent of an associative array which can't be provided with the same syntactic sugar in C unfortunately without some silly results.

However, what you can provide is a hashmap if your data conforms to key -> value pairs. What you will need is an appropiate hash function.

There's a decent simple example of a hashtable here:

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

酒几许 2024-07-17 12:24:50

如前所述,您需要一个关联数组或哈希映射或等效项。 此类代码的一个可能来源是 Hanson 的“C 接口和实现”(代码位于 Google 代码 - 使用前请仔细检查许可条款等。)

As already indicated, you need an associative array or hash map or equivalent. One possible source for such code is Hanson's "C Interfaces and Implementations" (code at Google Code - double check licencing terms etc before using it.)

一曲琵琶半遮面シ 2024-07-17 12:24:50

这是一个旧线程,但我认为这对于寻找实现的任何人来说仍然有用。 不需要太多代码; 我用大约 100 行代码完成了我的工作,没有像 Hank Gay 建议的那样使用任何额外的库。 我称它为字典,因为它(某种程度上)与 python 数据类型相似。 这是代码:

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

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] 语法,但这是我想出的最佳替代方案。

This is an old thread, but I thought this might still be useful for anyone out there looking for an implementation. It doesn't take too much code; I did mine in ~100 lines of without any extra library like Hank Gay suggested. I called it a dictionary since it parallels (sort of) the python datatype. Here is the code:

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

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)));
}

Unfortunately you can't replicate the list[x] syntax, but this is the best alternative I have come up with.

肤浅与狂妄 2024-07-17 12:24:50

在“plain C”中,您可以模仿使用字符串作为索引,但不是完全按照您想要的方式。 然而,这样做很少有用,而且主要是使代码变得不可读的绝佳方法。 您似乎想要的是能够在字典(或“哈希表”,如果您愿意)中使用字符串键,并且 C 中没有内置的数据结构。确切的设计取决于您的需求(事实上​​,如果这是家庭作业的一部分,您甚至可能不需要使用成熟的哈希表实现,但可能会使用性能较低的静态编码)。

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

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) 相同的事实。

In "plain C" you can mimic using a string as an index, but not QUITE in the way you seem to be wanting. However, doing so is seldom useful and mostly an excellent way of making your code unreadable. What you seem to be wanting is to be able to use string keys into a dictionary (or "hash table", if you prefer) and there are no built-in data structure for that in C. The exact design would depend on what you want (and, indeed, if this is part of homework, you may not even need to use a full-fledged hash-table implementation but could probably get away with less performant static coding).

An example using a string (OK, a char array) in the "index position) of an a[b] construct:

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;
}

The above is, as far as I can tell, legal C, with a well-defined output (the string "Tss ssi"). It relies on the fact that a[b] is defined to be the same as *(a+b).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文