char 数组初始化的几种方式
char str1[] = "helloworld"; // 末尾自动添加\0
char str2[] = { 'h', 'e', 'l', 'l', 'o' }; // 末尾没有\0
std::cout << strlen(str1) << std::endl; // 10 strlen 不记录\0的大小,但会寻找\0作为结尾
std::cout << sizeof(str1) << std::endl; // 11 sizeof 会记录\0的大小
std::cout << strlen(str2) << std::endl; // 无法确定,因为没有\0,不知道会在哪里结尾
std::cout << sizeof(str2) << std::endl; // 5
// *p指向 "helloworld",放在常量区
char *p = "helloworld";
p[1] = 'H'; // 尝试修改字符串常量的内容,非法操作
char str3[] = "helloworld";
str[1] = 'H'; // 正常操作 ,改变数组的元素,没问题
题目
如果不借助额外存储空间,请实现一个算法,完成字符串数组的反转
尝试看看resverce 的STL源代码
// 大神版 直接上STL源码 参考侯捷《STL源码解析》
template <class BidirectionalIterator>
inline void reverse_my(BidirectionalIterator first, BidirectionalIterator last) {
while (true) {
if (first == last || first == --last) {
return;
} else {
std::iter_swap(first++, last);
}
}
}
Bidirectional adj 双向的 n.双指向性
BidirectionalIterator 既可以自增,也可以自减
判断流程详解:
if (first == last || first == --last) {
return;
} else {
std::iter_swap(first++, last);
}
假设字符串是abcdef(6位 偶数位)
为了方便理解 这里的last 没有交换值,&f仅代表原来f所在的位置
if(first == last) | if(first == --last) (last自减) | swap(first++, last) (first 自增) | |
---|---|---|---|
第一次 | first = &a last = &(\0) | first = &a last = &f | first = &b last = &f |
第二次 | first = &b last = &f | first = &b last = &e | first = &c last = &e |
第三次 | first = &c last = &d | first = &c last = &d | first = &d last = &d |
第三次 | first == last = &d 退出循环 |
假设字符串是abcdefg(7位 奇数位)
if(first == last) | if(first == --last) (last自减) | swap(first++, last) (first 自增) | |
---|---|---|---|
第一次 | first = &a last = &(\0) | first = &a last = &g | first = &b last = &g |
第二次 | first = &b last = &g | first = &b last = &f | first = &c last = &f |
第三次 | first = &c last = &d | first = &c last = &e | first = &d last = &e |
第三次 | first = &d last = &e | first == last = &d 退出循环 |
// 大神版 直接上STL源码 参考侯捷《STL源码解析》
template <class BidirectionalIterator>
inline void reverse_my(BidirectionalIterator first, BidirectionalIterator last) {
while (true) {
if (first == last || first == --last) {
return;
} else {
std::iter_swap(first++, last);
}
}
}
// 屌丝版,虽然简单,但是可能面试官想要这种
// char str[] 默认str以\0结尾
// nStrlength 为不带/0的长度
void ReverseStr(char str[], int nStrlength) {
char *first = &str[0];
char *last = &(str[nStrlength]); //取到最后一位f + 1, 也就是/0的位置
while (true) {
if (first == last || first == --last) {
return;
} else {
char temp = *first;
*first = *last;
*last = temp;
first++;
}
}
}
// 屌丝进化版
// nStrlength 为不带/0的长度
void ReverseStr2(char str[], int nStrlength) {
char *first = &str[0];
char *last = &(str[nStrlength]); //取到最后一位f + 1, 也就是/0的位置
while (true) {
if (first == last || first == --last) {
return;
} else {
std::swap(*first++, *last);
}
}
}
int main() {
char str[] = "abcdef";
// char str[] = {'a', 'b' , 'c', 'd', 'e', 'f', '\0'}; // 如果没有\0,那么下面的操作就会越界,因为访问不到\0
//std::string str("helloworld");
std::cout << "str: " << str << std::endl;
std::cout << "sizeof(str): " << sizeof(str) << std::endl;
// str + sizeof(str) -1 == str[sizeof(str) -1] 为\0的位置
// std::reverse(str, str + sizeof(str) -1); // 直接上STL验证结果
// reverse_my(str, str + sizeof(str)-1); // 大神版测试
ReverseStr(str, sizeof(str)-1); //屌丝版老老实实的实现
std::cout << "str: " << str << std::endl;
return 0;
}