字符串常量和变量

理解C语言中字符串常量的修改问题

写代码的时候,发现对字符串常量改变的问题。网上找了一下资料,明白了

出处:http://blog.youkuaiyun.com/andylyc/archive/2008/01/16/2046225.aspx

 

请在(且只能在TC2.0)中运行下面代码,先不要看结果,想想会得到什么:   
  #include<stdio.h>   
  #include<stdlib.h>   
    
  int   
  main(   int   argn,   char*   argv[]   )   
  {   
          char*   szStringA   =   "Hello,world!";   
          char*   szStringB   =   "Hello,world!";   
    
          *szStringA   =   '-';   
          puts(   szStringB   );   
    
          return   0;   
  }   
  输出结果是:"-ello,world!";。是否和你想象的结果不一样呢?   
  ANSI   C明确说明:修改字符串常量,效果是未定义的  
  首先我们得清楚,如何才能得到字符串常量?只有一种方式:char*   szString   =   “Hello,world!”;这个声明得到一个字符串常量。那么char   szString[]   =   “Hello,world!”;可以吗?不可以!这样得到的是字符串变量。好了,回过来,由于ANSI   C没有要求编译器实现者如何具体对字符串常量进行处理,所以有些编译器会把相同的多个字符串常量看成一个(注意:这种优化仅有可能出现在字符串常量中,不 要把泛泛的用于其他类型的常量。如:int   num1   =   11;int   num2   =   11;虽然是两个相同的常量,但是修改num1不会影响num2),目的是为了节约内存空间,所以上面的例子中,当修改字符串a时,b也被修改了。从这里 可以看出,TC2.0有对字符串常量进行优化,而其他的编译器(如:DEVC++5.0)不一定也会优化,结果可能是无法通过编译,或者通过编译但是结果 是垃圾值。由于这些种种不确定因素,我们应尽量避免修改字符串常量。   
  如果必须修改字符串就没有办法呢?有!一定有!请注意:我们要的效果是修改字符。因此,只需要定义字符串变量,而不是字符串常量。前面说过,可以用数组的 方式定义char   szString[]   =   “Hello,world!”;;这样,在程序中就可以修改字符串了。   
  试试下面代码:   
  #include<stdio.h>   
  #include<stdlib.h>   
    
  int   
  main(   int   argn,   char*   argv[]   )   
  {   
          char   szStringA[]   =   "1234567890";   
          char   szStringB[]   =   "1234567890";  //sizeof(szStringB) != 10 ,sizeof(szStringB= 11
    
          szStringA[0]   =   '-';   
          puts(   szStringB   );   
    
          return   0;   
  }   
  没问题了吧。   
  OK,最后请记住:需要修改字符串,那么用char   szString[]   =   “Hello,world!”;进行声名!

<think> 我们是在讨论C++中的字符串拼接。用户使用了"std::str",但可能是指std::string。在C++中,拼接字符串常量变量可以使用多种方法。 常见方法: 1. 使用运算符+(但注意多次拼接可能效率低) 2. 使用std::stringstream 3. 使用append()成员函数 4. 使用C++11的std::to_string()将数字转换为字符串后再拼接 5. 使用格式化字符串(如sprintf或C++20的std::format) 由于问题中提到了“几个字符串常量变量”,我们将展示如何拼接字符串常量(如"hello")变量(可能是字符串、整数等)。 示例:假设有两个字符串常量"Hello, ""!",以及一个字符串变量name一个整数变量age,我们想生成"Hello, Alice! You are 25 years old." 我们将用两种常用方法展示:运算符+stringstream。 注意:如果变量是整数等类型,需要先转换为字符串。 方法1:使用运算符+(适合简单拼接) std::string result = "Hello, " + name + "! You are " + std::to_string(age) + " years old."; 方法2:使用stringstream(适合多类型变量复杂拼接) std::stringstream ss; ss << "Hello, " << name << "! You are " << age << " years old."; std::string result = ss.str(); 但注意:如果变量字符串(std::string)或者C风格字符串(const char*),都可以直接使用<<运算符。 另外,如果用户指的是C风格字符串(char数组),则可以用strcat或snprintf,但更推荐使用C++的std::string。 下面给出代码示例: </think> ### C++ 中拼接字符串常量变量的方法 在 C++ 中使用 `std::string` 拼接字符串常量变量有四种常用方法,根据场景选择最优方案: #### 1. **运算符 `+` 直接拼接**(简单场景) ```cpp #include <string> std::string concat_simple(const std::string& variable) { // 字符串常量 + 变量 + 字符串常量 return "Protocol: " + variable + " Version: v1.2"; } ``` **优点**:代码简洁直观 **缺点**:多次拼接会产生临时对象,效率较低 #### 2. **`append()` 成员函数链式调用**(高效拼接) ```cpp std::string concat_efficient(const std::string& var1, int var2) { std::string result; result.reserve(50); // 预分配内存提升性能 result.append("Device: ") .append(var1) .append(" ID: ") .append(std::to_string(var2)); // 数字转字符串 return result; } ``` **优点**:避免临时对象,内存分配最少 **适用场景**:高性能要求或循环中拼接 #### 3. **字符串流 `std::stringstream`**(混合类型拼接) ```cpp #include <sstream> std::string concat_mixed(const char* var1, double var2) { std::stringstream ss; ss << "Sensor: " << var1 // 拼接C风格字符串 << " Value: " << std::fixed << std::setprecision(2) << var2; // 格式化浮点数 return ss.str(); } ``` **优点**:支持任意类型自动转换 **适用场景**:含数字/布尔值等混合数据类型 #### 4. **C++20 格式化库 `std::format`**(现代方案) ```cpp // C++20 及以上版本 #include <format> std::string concat_modern(const std::string& name, int id) { return std::format("User: {} | ID: {:06d}", name, id); // 自动类型推导+格式化 } ``` **优点**:类型安全、语法简洁、支持格式化选项 **注意**:需要编译器支持 C++20 标准 --- ### 性能与安全性建议 1. **避免 C 风格拼接** ❌ 不要用 `strcat`:存在缓冲区溢出风险 ```cpp char buffer[50]; strcat(buffer, var); // 危险!可能越界 ``` 2. **大字符串优化** 使用 `reserve()` 预分配内存减少重分配次数: ```cpp std::string s; s.reserve(1024); // 预期大小 ``` 3. **字面量优化** 使用 `operator""s` 确保类型安全(C++14+): ```cpp using namespace std::string_literals; auto s = "Constant"s + var; // "s"后缀确保生成std::string ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值