c - C 如何获得字符串数组的数组偏移量?

标签 c arrays string

我正在为类做一些事情,我想根据特定条件使用不同的格式字符串。我这样定义它:

const char *fmts[] = {"this one is a little long", "this one is short"};

稍后,我可以使用

printf(fmts[0]);

printf(fmts[1]);

而且有效。

编译器在为我们做些什么吗?我的猜测是它会采用最长的字符串并将所有字符串都这样对齐存储。但我想从知道的人那里知道。谢谢

最佳答案

它的处理方式与任何其他数据类型相同。 “字符串”数组实际上是字符指针数组,所有 具有相同的大小。因此,为了获得指针的正确地址,它将索引乘以单个元素的大小,然后将其添加到基地址。

您的数组将如下所示:

      <same-size>
      +---------+
fmts: | fmts[0] | ------+
      +---------+       |
      | fmts[1] | ------|--------------------------+
      +---------+       |                          |
                        V                          V
                        this one is a little long\0this one is short\0

字符串本身的字符存储在数组中,它们存在于其他地方。按照你的方式,它们通常存储在只读内存中,尽管你也可以 malloc 它们,甚至可以将它们定义为可修改的字符数组,如:

char f0[] = "you can modify me without invoking undefined behaviour";

您可以使用以下代码看到它的运行情况:

#include<stdio.h>
const char *fmts[] = {
    "This one is a little long",
    "Shorter",
    "Urk!"
};
int main (void) {
    printf ("Address of fmts[0] is %p\n", (void*)(&(fmts[0])));
    printf ("Address of fmts[1] is %p\n", (void*)(&(fmts[1])));
    printf ("Address of fmts[2] is %p\n", (void*)(&(fmts[2])));

    printf ("\n");

    printf ("Content of fmts[0] (%p) is %c%c%c...\n",
        (void*)(fmts[0]), *(fmts[0]+0), *(fmts[0]+1), *(fmts[0]+2));
    printf ("Content of fmts[1] (%p) is %c%c%c...\n",
        (void*)(fmts[1]), *(fmts[1]+0), *(fmts[1]+1), *(fmts[1]+2));
    printf ("Content of fmts[2] (%p) is %c%c%c...\n",
        (void*)(fmts[2]), *(fmts[2]+0), *(fmts[2]+1), *(fmts[2]+2));

    return 0;
}

哪些输出:

Address of fmts[0] is 0x40200c
Address of fmts[1] is 0x402010
Address of fmts[2] is 0x402014

Content of fmts[0] (0x4020a0) is Thi...
Content of fmts[1] (0x4020ba) is Sho...
Content of fmts[2] (0x4020c2) is Urk...

在这里您可以看到数组元素的实际地址是等距的 - 0x40200c + 4 = 0x402010, 0x402010 + 4 = 0x402014

但是,这些值不是,因为它们指的是不同大小的字符串。字符串位于单个内存块中(在这种情况下 - 无论如何都没有必要),如下所示,* 字符指示各个字符串的开始和结束:

         |  +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f +0123456789abcdef
---------+-------------------------------------------------------------------
0x04020a0| *54 68 69 73 20 6f 6e 65 20 69 73 20 61 20 6c 69  This one is a li
0x04020b0|  74 74 6c 65 20 6c 6f 6e 67 00*53 68 6f 72 74 65  ttle long.Shorte
0x04020c0|  72 00*55 72 6b 21 00*                            r.Urk!.

关于c - C 如何获得字符串数组的数组偏移量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4103646/

相关文章:

c - 使用递归打印所有排列

c++ - 数组大小作为构造函数参数

php - 将 PHP 数组插入 MYSQL

javascript将字符串转换为带括号的int数组

arrays - bash 将带空格的字符串添加到数组中会添加两个元素

c - 如何读取文件同一行的多个字符串?

java - 不同行的 ListView 自定义适配器

c - 如何使用 GSL 在 C 中找到矩形矩阵的逆

c - 比较2D数组内部,函数内部的字符串

php - 使用字符串mysql更新表