在c++中定义字符串并将其作为函数参数传递的不同方式的差异

Difference in different way of defining string in c++ and passing these as parameter in function

本文关键字:参数传递 函数 方式 定义 c++ 字符 字符串 串并      更新时间:2023-10-16

我知道这些问题,我将告诉你们,可能很容易,但我真的遇到麻烦,而在c++中定义字符串。早先我是用C语言编码的。对于字符串,我使用char数组来存储字符串。在c++中有几种方法来定义字符串和初始化

例如:

1. char str[30];
2.string str="stackoverflow"; 
3.char *str="stackoverflow";
may be many more..

我也谷歌了一下,但没有得到满意的答案。

问题1:这些字符串的定义(我没有包括)是相同的还是不同的?如果是,那么如何?

问题2:我也有问题,而传递字符串作为函数参数。在所有定义中传递字符串作为参数的方法相同吗?如果没有,也请说明方法。

问题3:我们知道字符串以一个特殊字符''结束。如果我定义arr[4]并存储值"vinod"或arr[40]并存储值"vinod"会怎么样?第二种情况下的额外内存呢?虽然我没有尝试过使用程序。

不同类型的字符串:

char str[30];

创建一个30个字符的可修改数组。它可以用来保存字符串,但也可以用来保存原始数据。这类数组通常用作字节缓冲区,因为char的大小正好是一个字节。

string str="stackoverflow";

这将创建一个std::string对象,将字符串字面值"stackoverflow"传递给它的构造函数。string将获取该字符串文本的副本,并将其放入一个内部可修改数组中。Std::string比使用普通字符数组强大得多,因为它具有所有内置功能。

char *str="stackoverflow"

这将在内存中创建一个char指针,指向字符串字面量"stackoverflow"所在的只读位置。这是不可修改的,试图修改它会导致未定义的行为:

char *str="stackoverflow"
str[3] = 'h'; // undefined behaviour

作为参数传递的不同方式:

至于传递这些作为参数,那么它真的取决于你的目标是什么。第一个类型可以像这样传递:

void foo(char str[]);
void foo(char* str); // this is valid because arrays decay into pointers.
void foo(const char str[]); // prevents function from modifying the contents of the array.
void foo(const char* str); // same as above.
void foo(const char* const str); // prevents function from modifying contents of the array and what str points to.

第二种类型可以通过值或引用传递。如果你有意要传递std::string的副本,那么你可以按值传递。如果你想传递std::string而不是一个副本,那么你可以通过引用传递。如果出于性能原因(为了避免代价高昂的复制)不想通过引用传递,也不想让函数修改字符串,那么可以通过const引用传递。

void foo(std::string str); // pass by value. A copy is passed into here.
void foo(std::string& str); // pass by reference.
void foo(const std::string& str); // avoid the copy but prevent this function from modifying your string.

最后一个类型应该作为const传递,因为它不能被修改。

void foo(const char* str);
void foo(const char str[]); // this is valid because arrays decay into pointers.

您展示了三个声明

1.char str[30];
2.string str="stackoverflow"; 
3.char *str="stackoverflow"; may be many more..

第一个声明了一个30个字符的字符数组。

第二个声明了一个类std::string的对象,并用字符串字面值"stackoverflow"初始化它。

第三个声明了一个指向char的指针,该指针由字符串字面量"stackoverflow"的第一个字符的地址初始化。

在c++中最后一个声明是不正确的,因为在c++中字符串字面值具有常量字符数组的类型。正确的写法是

3.const char *str="stackoverflow"; may be many more..

所以你声明了三个不同类型的不同对象。

类std::string有一个构造函数,允许隐式地将char指针转换为std::string类型的对象。

如果你有一个参数为std::string的函数例如

void f( std::string s );

则可以传递上面声明的任何

对象1。

char str[30] = "stackoverflow";
f( str );

2。

std::string str = "stackoverflow"; 
f( str );

3。

const char *str = "stackoverflow";
f( str );

在这三种情况下,函数将在自身内部处理类型为std::string的对象。

string str="stackoverflow";

假设你指的是std::string,这将创建一个类型为const char[]的字符串字面量"stackoverflow",然后调用std::string(const char*)构造函数来创建一个包含"stackoverflow"的std::string对象。

char *str="stackoverflow"; 

因为字符串字量是const char[]类型,所以给它赋值char*是不赞成的,从c++ 14开始是非法的,但是大多数编译器仍然接受它。它在堆栈上创建一个字符串字面值"stackoverflow",并将第一个字符's'的地址分配给指针str

我也有问题,而传递字符串作为函数参数。在所有定义中传递字符串作为参数的方法相同吗?如果没有,也请说明方法。

在c++中,你通常只想传递一个std::string给一个函数,以避免破坏东西。如果您想避免复制std::string对象,请考虑传递const std::string&

我们知道string以一个特殊字符''结束。如果我定义arr[4]并存储值"vinod"或arr[40]并存储值"vinod"会怎么样?第二种情况下的额外内存呢?

在第一个示例中,您使用string来存储字符串字面值,该字符串字面值对于数组来说太大,导致缓冲区溢出。

对于arr[40],你的数组足够大,它会很乐意接受字符串字面值并从索引0开始存储它。

不需要的剩余空间仍然被占用。