在c++中定义字符串并将其作为函数参数传递的不同方式的差异
Difference in different way of defining string in c++ and passing these as parameter in function
我知道这些问题,我将告诉你们,可能很容易,但我真的遇到麻烦,而在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开始存储它。
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 使用指向成员的指针将成员函数作为参数传递
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 将成员函数指针作为参数传递给模板方法
- 如何在C++中将迭代器作为函数参数传递
- 将附加参数传递给使用 beast::bind_front_handler 调用的函数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 如何传递带有通过引用传递的结构参数的函数?
- 如何在 c++ 中将函数作为参数传递?
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- 为什么我不能将引用作为 std::async 的函数参数传递
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 将__device__ lambda 作为参数传递给 __global__ 函数
- 是否可以在不填充自己的参数的情况下将模板函数作为参数传递?
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 将函数作为参数传递以避免重复代码
- 如何在类(C )中作为参数传递函数