我应该如何在C结构中声明字符串?

时间:2014-06-30 19:34:32

标签: c arrays string pointers

你好我是这个网站的新手,我需要一些帮助来理解在C语言中编码需要字符串的结构时会被视为“规范”的内容。基本上我想知道在使用C中的结构来跟踪结构所需的所有内存时,下列哪种方式将被视为“行业标准”:

1)固定大小字符串:

typedef struct
{
    int damage;
    char name[40];
} Item;

我现在可以使用sizeof(Item)

获取大小

2)字符数组指针

typedef struct
{
    int damage;
    char *name;
} Item;

我知道我可以使用第二个变量存储name的大小,但还有其他方法吗?

i)使用固定大小(1)

还有其他优势吗?
char name[40];

与执行以下操作并使用指向char数组的指针(2)?

char *name;

如果是的话,有什么好处?

ii)另外,使用指向char数组(2)的指针的字符串是否会顺序存储在结构之后(紧跟在指向字符串的指针之后),还是存储在内存中的其他位置? / p>

iii)我想知道如何找到char *字符串变量的长度(不使用size_t或整数值来存储长度)

3 个答案:

答案 0 :(得分:6)

字符串基本上有3种常见约定。所有这三个都是在野外发现的,包括内存表示和存储/传输。

  1. 固定尺寸​​。访问非常有效,但如果实际长度变化,则两者都浪费空间,需要使用以下方法之一来确定“真实”内容的结束。
  2. 长度前缀。动态分配中包含额外空间以保持长度。从指针中,您可以找到字符内容和紧接其前面的长度。示例:BSTR有时将长度编码为短字符串的空间效率更高。示例:ASN-1
  3. 终止。字符串一直延伸到第一次出现终止字符(通常是NUL),并且内容不能包含该字符。变化使终止两个NUL按顺序,允许单个NUL字符存在于字符串中,然后通常将其视为字符串的打包列表。其他变体使用诸如字节填充之类的编码(UTF-8也可以工作)来保证存在一些保留用于终止的代码,这些代码不能出现在内容的编码版本中。
  4. 在第三种情况下,有strlen之类的函数来搜索终结符并找到长度。

    使用指针的两种情况都可以指向紧跟在结构的固定部分之后的数据,如果你仔细地分配它。如果要强制执行此操作,请在结构末尾使用灵活数组(无需指针)。像这样:

    typedef struct
    {
        int damage;
        char name[]; // terminated
    } Item;
    

    typedef struct
    {
        int damage;
        int length_of_name;
        char name[];
    } Item;
    

答案 1 :(得分:1)

1) is there any other advantage to using the fixed size (1)

char name[40];

versus doing the following and using a pointer to a char array (2)?

char *name;

and if so, what is the advantage?

将您的数组声明为char name[40];名称空间已经分配,​​您可以将信息从name复制到name[0]name[39]。但是,在char *name;的情况下,它只是一个字符指针,可用于指向内存中的现有字符串,但是,除非您分配内存以保存,否则它本身不能用于复制信息那些信息。因此,假设您要将30个字符的字符串复制到name,并声明为char *name;,则必须先使用malloc 30个字符加上分配一个额外字符保持以null结尾的字符:

char *name;
name = malloc (sizeof (char) * (30 + 1));

然后您可以自由地将信息复制到name。动态分配的一个优点是,如果您存储在名称中的信息增长,则realloc可以name内存。超过30个字符。在为name分配内存后的另一个要求是,您负责释放不再需要的内存。这是使用一个而不是另一个的利弊/要求的粗略概述。

答案 2 :(得分:0)

如果您知道所需字符串的最大长度,则可以使用字符数组。它确实意味着您将使用比您通常使用动态分配的字符数组更多的内存。另外,如果您使用的是C ++,请查看CString。您可以使用strlen找到字符数组的长度。在静态分配的情况下,我相信它将是变量的一部分。动态可以在堆上的任何位置。