指向字符与字符串的指针
Pointer to char vs String
考虑这两段代码。他们将基数10转换为基数N,其中N
是给定字母表中的字符数。实际上,它们生成给定字母表中字母的排列。假设1等于字母表中的第一个字母。
#include <iostream>
#include <string>
typedef unsigned long long ull;
using namespace std;
void conv(ull num, const string alpha, string *word){
int base=alpha.size();
*word="";
while (num) {
*word+=alpha[(num-1)%base];
num=(num-1)/base;
}
}
int main(){
ull nu;
const string alpha="abcdef";
string word;
for (nu=1;nu<=10;++nu) {
conv(nu,alpha,&word);
cout << word << endl;
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef unsigned long long ull;
void conv(ull num, const char* alpha, char *word){
int base=strlen(alpha);
while (num) {
(*word++)=alpha[(num-1)%base];
num=(num-1)/base;
}
}
int main() {
char *a=calloc(10,sizeof(char));
const char *alpha="abcdef";
ull h;
for (h=1;h<=10;++h) {
conv(h,alpha,a);
printf("%sn", a);
}
}
输出相同:
b
c
d
aa
ba
ca
da
不,我没有忘记反转字符串,为了代码澄清,反转被删除了
出于某种原因,速度对我来说非常重要。我测试了根据上面的例子编译的可执行文件的速度,并注意到使用string
在C++中编写的可执行程序比使用char *
在C中编写的快10倍。
每个可执行文件都使用GCC的-O2
标志进行编译。我运行的测试使用了更大的数字来转换,比如1e8和更多。
问题是:在这种情况下,为什么string
的速度不如char *
?
您的代码片段与不等价。*a='n'
不会而附加到char
数组。它将数组中的第一个char
更改为'n'
。
在C++中,std::string
s应该优先于char
数组,因为它们更容易使用,例如,只需使用+=
运算符即可进行追加。
此外,char
阵列不会自动为您管理内存。也就是说,std::string
比手动管理的char
阵列更不容易出错。
跟踪您得到的代码:
*a='n';
// 'n0000'
// ^
// a
++a;
// 'n0000'
// ^
// a
*a='o'
// 'no000'
// ^
// a
最后,a指向它的原始地址+1,wich是o。如果你打印a,你会得到"o"。
不管怎样,如果你需要"什么都不需要"而不是"不需要"怎么办?它不适合5个字符,你需要重新分配内存等。这就是字符串类在幕后为你做的事情,而且速度足够快,所以几乎在任何情况下都不是问题。
可以同时使用char*和string来处理C++中的一些文本。在我看来,字符串添加比指针添加慢得多。为什么会发生这种情况?
这是因为当您使用char数组或处理指向它的指针(char*)时,内存只分配一次。用"加法"描述的只是指向数组的指针的一次迭代。所以这只是一个指针的移动。
// Both allocate memory one time:
char test[4];
char* ptrTest = new char[4];
// This will just set the values which already exist in the array and will
// not append anything.
*(ptrTest++) = 't'
*(ptrTest++) = 'e';
*(ptrTest++) = 's';
*(ptrTest) = 't';
当您使用字符串时,+=
运算符实际上会将字符附加到字符串的末尾。为了实现这一点,每次向字符串添加内容时,都会动态地分配内存。这个过程所花费的时间比仅仅迭代一个指针要长。
// This will allocate space for one character on every call of the += operator
std::string test;
test += 't';
test += 'e';
test += 's';
test += 't';
std::string a(2,' ');
a[0] = 'n';
a[1] = 'o';
在构造函数中更改字符串的大小,或者使用reserve、resize方法,这是您的选择。
在你的问题中,你混合了不同的东西,一种是字节的原始表示,可以被解释为字符串,没有语义或检查,另一种是带检查的字符串的抽象,相信我,安全性和避免segfault更重要,因为segfault可能导致代码注入和权限提升超过2ms。
从std::string文档(此处)中可以看到,
basic_string& operator+=(charT c)
相当于在该字符串上调用push_back(c)
,因此
string a;
a+='n';
a+='o';
相当于:
string a;
a.push_back('n');
a.push_back('o');
push_back
确实比原始指针操作处理更多,因此速度较慢。例如,它负责字符串类的自动内存管理。
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- 初始化或分配空字符串文字到指向 C 中的 char 的指针或指向 C++ 中 const char 的指针的原因是什么
- 使用指针初始化 char 数组或字符串 C++
- 指针保留字符串
- Visual c ++,使用字符串引用/指针调用 dll 函数
- strcpy 在类中无法使用字符串指针
- C++为 void 指针分配一个字符串
- OpenGL 统一名称指针作为字符串
- 如何将字符串指针数组转换为字符串类型的智能指针向量?
- 转换指针引用的字符串
- 未分配释放C++(C 字符串)指针
- 为什么 C 样式字符串的工作空指针检查不?
- 为什么多维数组中的空字符串文本衰减为空指针?
- 使用终止程序的指针在数组中输入字符串
- 将指针作为缓冲区传递到第一个字符串元素
- 指针 - 字符串C
- C++:更改指针字符串的值
- 使用带字符指针字符串的基于范围的For循环
- 转换/解析指针字符串和双精度
- 有问题分配字符串指针字符串值