简体   繁体   English

在 C 中,为什么不能在声明后将字符串分配给 char 数组?

[英]In C, why can't I assign a string to a char array after it's declared?

This has been bugging me for a while.这已经困扰我一段时间了。

struct person {
       char name[15];
       int age;
};
struct person me;
me.name = "nikol";

when I compile I get this error:当我编译时出现此错误:

error: incompatible types when assigning to type 'char[15]' from type 'char *'错误:从类型“char *”分配给类型“char[15]”时类型不兼容

am I missing something obvious here?我在这里遗漏了一些明显的东西吗?

Arrays are second-class citizens in C, they do not support assignment.数组是 C 中的二等公民,它们不支持赋值。

char x[] = "This is initialization, not assignment, thus ok.";

This does not work:这不起作用:

x = "Compilation-error here, tried to assign to an array.";

Use library-functions or manually copy every element for itself:使用库函数或手动复制每个元素:

#include <string.h>
strcpy(x, "The library-solution to string-assignment.");

me.name = "nikol"; is wrong !!是错的 !! you need to use strcpy()你需要使用strcpy()

when you do x = "Some String" , actually you are putting the starting address of the static string "Some String" into variable x .当您执行x = "Some String" ,实际上您将静态字符串"Some String"的起始地址放入变量x In your case, name is a static array, and you cannot change the address.在您的情况下, name是一个静态数组,您不能更改地址。 What you need, is to copy your string to the already allocated array name .您需要的是将您的字符串复制到已分配的数组name For that, use strcpy() .为此,请使用strcpy()

First of all, you need to know the following points:首先,您需要了解以下几点:

  • In C, text strings are just arrays.在 C 中,文本字符串只是数组。
  • In C, array variables are basically just pointers.在 C 中,数组变量基本上只是指针。

So, char mytext[12];所以, char mytext[12]; is essentially just declaring a char pointer called mytext that stores the address of the first (zero'th) element of the array/string.本质上只是声明一个名为mytext的字符指针,该指针存储数组/字符串的第一个(第零个)元素的地址。

This code is therefore valid:因此,此代码有效:

#include <stdio.h>
int main(int argc, char *argv[])
{
    const char a[] = "Hello";
    const char *b = a;
    printf("%s\n", b);
    return 0;
}

The important thing to note here is that re-assigning b doesn't change the contents of whatever it points to - it changes the thing that it points to.这里要注意的重要一点是,重新分配b不会改变它指向的任何内容——它改变它指向的东西

However, there are cases where arrays and pointers behave differently.但是,在某些情况下,数组和指针的行为会有所不同。 In the example above, a cannot be reassigned.在上面的例子中, a不能被重新分配。 If you try, you'll get an error .如果你尝试,你会得到一个错误

To go back to you original example, this structure:回到你原来的例子,这个结构:

struct person{
    char name[15];
    int age;
};

...can be thought of as a 19-byte structure* of which the first 15 bytes are earmarked for storing a string. ...可以被认为是一个 19 字节的结构*,其中前 15 个字节专门用于存储字符串。 The name attribute stores the address of the first byte, so you know where those 15 bytes live in memory - you just need to write something useful into them. name属性存储第一个字节的地址,因此您知道这 15 个字节在内存中的位置 - 您只需要向其中写入一些有用的内容。

This is where functions such as sprintf() or strcpy() come into play - they copy data into the address defined by name rather than re-assigning name itself.这就是sprintf()strcpy()等函数发挥作用的地方——它们将数据复制到name定义的地址中,而不是重新分配name本身。

* Assuming that sizeof(int) is 4 and the structure is not padded, of course... * 假设sizeof(int)是 4 并且结构没有被填充,当然...

The initialization: 初始化:

char name[15]

is creating a char array, 15 bytes in size. 正在创建一个15字节的char数组。

"nikol" is a string literal, which is type 'char *', ie a pointer to a string. “nikol”是一个字符串文字,类型为“char *”,即指向字符串的指针。 They are incompatible types. 它们是不兼容的类型。 You need to copy the string into the array, like so: 您需要将字符串复制到数组中,如下所示:

strcpy(me.name, "nikol")

You first must understand how memory assignment work in array .您首先必须了解内存分配如何在数组中工作

When you declare the name of an array, that name actually works as pointer and point to the first element of the array.当您声明数组的名称时,该名称实际上用作指针并指向数组的第一个元素。

struct person {
       char name[15];
       int age;
};

Here name is pointing to the memory address of first element of array ie name[0] .这里name指向数组第一个元素的内存地址,即name[0] You have declare the character array so the each block of memory have 1 byte of size.您已经声明了字符数组,因此每个内存块都有 1 个字节的大小。 And name is also pointing to the 1 byte of memory.并且名称也指向内存的 1 个字节。

struct person me;
me.name = "nikol";

me.name = "nikol"; me.name = "nikol"; won't work.不会工作。 You are assigning 5 byte of data to 1 byte of storage and also without dereferencing the the pointer variable.您将 5 个字节的数据分配给 1 个字节的存储空间,并且没有取消引用指针变量。 For better understanding try this code为了更好地理解试试这个代码

struct person me;
*me.name = 'n';

Here I have deference the pointer name and assigned 1 byte of data.在这里,我尊重了指针名称并分配了 1 个字节的数据。 This code will work perfectly fine这段代码将工作得很好

printf("%c" , me.name[0]);

Output will be n.输出将为 n。

This is why we have to use strcpy() function.这就是我们必须使用 strcpy() 函数的原因。 Strcpy() assign the each character of the string constant to the each block of memory of the array. strcpy() 将字符串常量的每个字符分配给数组的每个内存块。 This is why it will work.这就是为什么它会起作用。

strcpy(me.name , "nikol");

Use strcpy() function (of string.h library) :)使用strcpy()函数( string.h库的):)

main(){
struct person{
       char name[15];
       int age;
};
struct person me;
strcpy(me.name,"nikol");
}

You are trying to change the memory address of an array pointer (by giving me.name = "nikol") which is impossible.您正在尝试更改数组指针的内存地址(通过给 me.name = "nikol"),这是不可能的。 Name of array (me.name) is a fixed pointer and cannot be changed to point to a new location of string ("nikol") because memory address of an array pointer is on the first member of that array.数组名称 (me.name) 是一个固定指针,不能更改为指向字符串 ("nikol") 的新位置,因为数组指针的内存地址位于该数组的第一个成员上。 If you want to assign a string after declared (me.name = "nikol"), use external pointer *name instead because external pointer floats outside array so its value can be changed on-the-fly.如果要在声明后分配字符串 (me.name = "nikol"),请改用外部指针 *name,因为外部指针浮动在数组外,因此可以即时更改其值。

struct person {
       char *name;
       int age;
};
struct person me;
me.name = "nikol"; // no error

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM