字符串大小和地址间距的指针数组不匹配

Pointer array of strings size and address spacing do not match

抱歉,如果这是一个愚蠢的问题。我正在尝试自学一些编程,但在这里陷入了一些困惑。代码:

#include <stdio.h>

void main()
{
    int i;

    char *array[5]={"Apples", "mangoes", "grapes", "bananas", "oranges"};

    printf("THIS IS FROM THE ARRAY:\n");
    for(i = 0; i < 5; i++)
    {
        printf("String=%s | ", array[i]);
        printf("Address of string literal = %i", array[i]);
        printf(" | Size = %u\n",sizeof(array[i]));
    }
}

产生输出: Output Image

THIS IS FROM THE ARRAY:
String=Apples | Address of string literal = 4210688 | Size = 8
String=mangoes | Address of string literal = 4210695 | Size = 8
String=grapes | Address of string literal = 4210703 | Size = 8
String=bananas | Address of string literal = 4210710 | Size = 8
String=oranges | Address of string literal = 4210718 | Size = 8

尽管 sizeof 输出显示大小为 8,但为什么地址之间的差异不始终为 8?

4210688 4210695(相差 7) 4210695 4210703(相差8) 4210703 4210710(相差 7) 4210710 4210718(相差8)

如果我的怀疑是正确的(这些不是字符串在内存中的地址,而只是指针或其他东西的地址),我将如何更改我的代码以列出实际字符串所在的地址驻留在内存中? 我在使用代码块 IDE、GNU GCC 编译器的 Windows 64 位系统上。如果您需要更多相关信息,我很乐意提供。

sizeof(array[i]) 给出 char * 的大小而不是字符串的长度。使用 strlen()+1 作为字符串中的字节数。

7 的差异对于 6 个字母的单词(+ 终止 NUL 字符)来说非常有意义。

此外,正如 chux 所说,您应该使用 %p 来打印指针值(为了更加正确,参数应该转换为 (void *))。

如果打印strlen(array[i])而不是sizeof(array[i]),可以发现char*的数组是连续存在的。

main() 应该 return 整数。 void main() 不是标准。

您应该为数组声明 const char*,而不是 char*。不可修改。

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

int main()
{
    int i;

    const char* array[5] = { "Apples", "mangoes", "grapes", "bananas", "oranges" };

    printf("THIS IS FROM THE ARRAY:\n");
    for (i = 0; i < 5; i++)
    {
        printf("String=%s | ", array[i]);
        printf("Address of string literal = %i", array[i]);
        printf(" | Size = %u\n", strlen(array[i]));
    }

    return 0;
}

首先,在打印地址时,您应该使用 %p 格式说明符并将参数转换为 void *

也就是说,正在打印的地址 存储字符串的地址。如果仔细观察每个指针地址之间的差异,您会发现这些差异与每个字符串的大小完全匹配。字符串文字通常存储在 read-only 数据段中,在这种情况下,您的每个字符串恰好在内存中是连续的。

如果您要打印每个数组元素的地址(每个元素都是一个指针),那么您会看到它们之间的差异为 8。