Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C如何获得字符串数组的数组偏移量?_C_Arrays_String - Fatal编程技术网

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

C如何获得字符串数组的数组偏移量?,c,arrays,string,C,Arrays,String,我正在为类做一些事情,我想根据特定条件使用不同格式的字符串。我是这样定义的: const char *fmts[] = {"this one is a little long", "this one is short"}; 以后,我可以用 printf(fmts[0]); 或 它是有效的 编译器在为我们做什么吗?我的猜测是,这将需要最长的字符串并将所有字符串按那样对齐存储。但我想从知道的人那里知道。感谢fmts指向char的指针。它不指向字符串本身 换句话说:fmts[0]和fmts[1]的

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

const char *fmts[] = {"this one is a little long", "this one is short"};
以后,我可以用

printf(fmts[0]);

它是有效的


编译器在为我们做什么吗?我的猜测是,这将需要最长的字符串并将所有字符串按那样对齐存储。但我想从知道的人那里知道。感谢

fmts指向char的指针。它不指向字符串本身


换句话说:
fmts[0]
fmts[1]
的地址差异在于类型
char*

的大小。答案是,你本身没有字符串数组,你有一个指向
char
的指针数组。指针的大小都相同,
printf()
只需取消引用它们。

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

您的阵列将如下所示:

      <same-size>
      +---------+
fmts: | fmts[0] | ------+
      +---------+       |
      | fmts[1] | ------|--------------------------+
      +---------+       |                          |
                        V                          V
                        this one is a little long\0this one is short\0
您可以通过以下代码看到此操作:

#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;
}
在这里您可以看到数组元素的实际地址是等距的-
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!.

是的,编译器将使第一个指针指向第一个字符串的第一个字符,第二个指针指向第二个字符串的第一个字符


因为它是“指向字符的指针数组”,所以每个指针都可以指向任何位置,不需要等长或任何东西。

您没有字符串数组。您有一个指向字符串的指针数组,或者更准确地说,有一个指向字符串的第一个字符的指针数组。所有指针都具有相同的大小,因此不会出现确定偏移量的问题

如果你真的想要一个字符串数组,你必须声明类似的东西

const char fmts[][64] = { "this one is a little long", "this one is short" };
i、 你必须声明一个数组。在这种情况下,您有责任为实际字符串数组指定足够的固定大小(在我的示例中为
64
),该值将确定从一个字符串到数组中下一个字符串的固定偏移量


正如您在问题中正确指出的,在本例中可以指定的最小大小由数组中最长的字符串决定。但是,编译器不会为您计算它。您必须自己明确指定它。

您没有声明字符串数组。您声明了一个指向字符串的指针数组。字符串数组如下所示:

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

正如您所见,您必须将最大长度指定为第二个数组维度(只有多维数组的第一个维度可以在C中隐式确定)。

使用ASCII字符绘制图表一定很有趣,hahaDamn您写的东西与我几秒钟前写的几乎完全相同!假的!您必须将
&fmts[0]
转换为
char*
指针,才能使您的算术工作。C指针算法针对类型进行调整!希望您不介意,我将您的代码重新编译成文本,这样它就不会遇到C类型扩展的问题。
         |  +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!.
const char fmts[][64] = { "this one is a little long", "this one is short" };
char fmts[][40] = {"this one is a little long", "this one is short"};