字符串与字符串文字:直接赋值还是strcpy/strncpy?
我想我在理解字符串和字符串文字时遇到了一些问题 这是我从我的类中学到的,当传递给函数时,const char*表示这是字符串文字,而char*表示字符串 假设我有一个结构声明:字符串与字符串文字:直接赋值还是strcpy/strncpy?,c,struct,strcpy,C,Struct,Strcpy,我想我在理解字符串和字符串文字时遇到了一些问题 这是我从我的类中学到的,当传递给函数时,const char*表示这是字符串文字,而char*表示字符串 假设我有一个结构声明: struct node{ char *name; struct node *next; }; 还有一个函数,这是我想要实现的函数: void load_buffer(struct node *input_node, char *input_name); 此函数用于将输入_名称分配给结构的成员名称 我的
struct node{
char *name;
struct node *next;
};
还有一个函数,这是我想要实现的函数:
void load_buffer(struct node *input_node, char *input_name);
此函数用于将输入_名称分配给结构的成员名称
我的困惑来自这里。在load_buffer的主体中,我是否应该写入:
input_node->name = input_name;
或者我应该使用strcpy/strncpy来做这个
strcpy(input_node->name, input_name);// Suppose it's safe in this case.
总之,我不确定是否应该使用直接赋值或strcpy族函数将字符串/字符串文本赋值给结构的成员
谢谢你的帮助。:) 在指针分配的情况下,每个节点中的指针将指向相同的位置。因此,节点将始终指向更新的值。如果要使每个节点包含不同的
输入
,则此方法不适合您的要求
input_node->name = input_name;
如果是strcpy,每个节点中的指针将指向不同的位置。在此之前,您需要为每个指针创建内存
input_node->name = malloc(strlen(input_name)+1); //Allocate memory first.
strcpy(input_node->name, input_name);// Suppose it's safe in this case.
可视化:
。。。传递给函数时,const char*
表示这是字符串文字,而char*
表示字符串
不完全是const char*
声明函数不会尝试修改字符串。因此,它非常适合字符串Literal,因为它们无法修改
对于你的问题,答案是它取决于你的实际需求。但是,如果结构可以在函数之后保持,并且字符串可以在调用者中更改,则只需存储传递的指针。让我们看看下面的代码:
void load_buffer(struct node *input_node, const char *input_name) {
input_node->name = name;
}
struct node nodes[2];
char buf[4];
const char *data[] = { "foo", "bar"};
for (int i=0; i<2; i++) {
strcpy(buf, data[i]); // suppose it is read from somewhere (file, stdin, socket)
load_buffer(node + i, buf);
}
但是当节点不再使用时,您应该释放
名称成员…首先解决一些术语:
- 这是字符串文字:
“我是字符串文字”
- 这是一种类型:
char*
(也称为指向char的指针)
- 这也是一种类型:
常量字符*
(也称为指向常量字符的指针)
- 这是类型为
char*
:char*str
- 这是类型为
const char*
:const char*cstr
指针不是字符串文字。指针可以指向字符串文字、数组,也可以指向单个元素,也可以为null
在C
中,字符串是以null结尾的字符数组
在C
中,可以将char*
变量指定给字符串文字,但修改字符串文字是非法的,因此强烈建议不要这样做。允许这样做的原因是历史的
char* a = "asd"; // allowed, but frowned upon
// a points to a string literal, so we can say a is a string
// a is not a string literal
char b = 'x';
char* c = &b;
// c points to a single char
// we cannot say c is a string
char d[10] = "asd";
// d is a char array. Its content is a string, so we can say d is a string.
// d is not a string literal
// the string literal is copied into the array d
char* e = d; // or equivalent char* e = &d[0];
// e points to a string
char f[4] = {'a', 's', 'd', '\0'};
// f is an array. Its content is a string, so we can say f is a string
char* g = f;
// g points to a string. We can say g is a string
char h[3] = {'a', 's', 'd'};
// h is an array. Its content is NOT a string, because the char array is not null terminated
char* i = h;
// i is not a string
现在再次检查上述内容,但不要将char
替换为const char
,所有注释仍然有效(除了`const char*a=“asd”现在可以了)
现在来谈谈手头的问题
有两种情况:
每个节点都有自己的字符串,并且“拥有”该字符串。每个节点负责为字符串分配内存并释放该内存。字符串的寿命与节点的寿命相同。在这种情况下,使用malloc
和strcpy
为每个节点创建一个字符串。当节点被销毁时,不要忘记释放字符串。这是最常见的场景,可能是您想要的
节点不拥有自己的字符串,而是指向外部字符串。不允许为该字符串分配或释放内存。还有另一个实体负责管理该字符串的生存期,并确保该字符串至少在节点处于活动状态时处于活动状态。字符串可以在没有内存泄漏的情况下超过节点
例如,考虑这种情况:
- 有一个字符串资源列表。此列表拥有这些资源。此列表将使用场景1
- 我们需要保留两个不同的R排序顺序。因此我们有两个列表A和B,它们将使用场景2:A和B中的每个节点都指向一个R字符串
输入节点->名称=输入名称考虑到输入\u名称
以后不会更改,code>应该可以。这取决于您想要的语义:结构
是否必须拥有引用的字符串,以及如何分配它?如果您有指针,则需要在使用strcpy
之前将其指向有效的位置。至于使用哪一种,这要看情况而定。您是否总是使用字符串文字?您需要修改字符串吗?附加到它们?不,我不需要修改字符串,我将使用的“字符串”是从文件中读取的,那么这是否表明我应该使用直接赋值而不是strcpy族函数?所有节点的“字符串”都是相同的?如果是malloc()
,则必须free()
。
char* a = "asd"; // allowed, but frowned upon
// a points to a string literal, so we can say a is a string
// a is not a string literal
char b = 'x';
char* c = &b;
// c points to a single char
// we cannot say c is a string
char d[10] = "asd";
// d is a char array. Its content is a string, so we can say d is a string.
// d is not a string literal
// the string literal is copied into the array d
char* e = d; // or equivalent char* e = &d[0];
// e points to a string
char f[4] = {'a', 's', 'd', '\0'};
// f is an array. Its content is a string, so we can say f is a string
char* g = f;
// g points to a string. We can say g is a string
char h[3] = {'a', 's', 'd'};
// h is an array. Its content is NOT a string, because the char array is not null terminated
char* i = h;
// i is not a string