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

问题描述

很抱歉,如果这是一个愚蠢的问题。我试图自学一些编程,但是这里有些混乱。代码

#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)

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

解决方法

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

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

如果要打印每个数组元素的地址(每个数组元素都是一个指针),则每个数组元素之间的差值为8。

,

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

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

此外,正如chux所说,您应该使用%p打印指针值(并且更正确的是,参数应强制转换为(void *))。

,

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

main()应该返回int。 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;
}