char* 、char[]、与string 的区别,以及求取字符串长度

本文最后更新于:2021年1月15日 下午

普通char[]数组的使用

看一个小案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//运行环境 VS2017
#include <iostream>
using namespace std;

int main()
{
char as[10] = "123456789";

cout << "数组内容:"<<as << endl;

cout << "输入数组内容:";

cin >> as; //这样赋值是可以的

cout << "新的数组内容:" << as;
}

执行结果:

1
2
3
数组内容:123456789
输入数组内容:fox
新的数组内容:fox
  1. char数组的赋值语句中,“123456789”这一串长度为
  2. cin>>as这样的输入数组的方式是可以的,但是一旦长度超过了9(\0是在输入中默认填充的),就会引发异常,至少Windows平台的VS2017是如此,这样的输入方式非常的不安全,慎用。

https://blog.csdn.net/ksws0292756/article/details/79432329

一个常见的错误——指针与元素

问题出在我上数据结构对串进行操作时需要对一段字符串的长度进行计算,当时卡住了壳,之后再次回顾时发现还是自己粗心大意,基础太差,所以再这里做一个总结归纳。
这是我当初的代码

1
2
3
4
5
6
7
int getLength(char *p)
{
int length=0;
for(;p!='\0';p++)//p是一个指针
length++;
return length;
}

我实际上调用的时getLength("asdfg");然后程序运行了好长一段时间,结果是一个巨大的负值。事实上是for循环的判断条件出错了。p是指针,直接用指针与字符‘\0’作比较会出现问题,所以会有这样的结果。
所以实际上可以说是少写了一个符号*导致的。所以正确的代码是

1
2
3
4
5
6
7
int getLength(char *p)
{
int length=0;
for(;*p!='\0';p++)//这里的*是解引用符,表示取出地址对应的元素
length++;
return length;
}

char* 、char[]的区别

  • char* 是字符型指针类型,用来声明一个变量是字符指针类型的。
  • char[]则是一个字符数组,使用一段连续的内存空间存储多个字符。

他们两个在普通地方差别挺明显的,而对于函数形参来说几乎没有区别。

普通位置时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*-----编译环境VC2010-----*/
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
char a[] = {'a','b','\0'};
char * b = "abc";
cout<<a<<endl;
cout<<b<<endl;
a[0] = 's';
b[0] = 's';
system("pause");
return 0;
}

代码会在b[0] = 's';处停止运行,发生错误,原因在于char []char *内存分区是不同的。字符数组char[]存放于_栈区_,_是可以进行读写操作的_。而char *所指向的字符串abc是存放于_文字常量区_的,_文字常量区_是不能更改的,_是只读区域_。所以尝试对其进行修改时就会报错。

作为函数参数时

当数组作为函数参数时,实际上传递的是数组首元素的地址。
即C++只是把形参数组名作为一个指针变量来处理,用来接收从实参传过来的地址。
——(谭浩强-C++程序设计第三版)

1
2
3
4
//所以对于以下两个函数,完全的等价
int fun(int num,char a[])

int fun(int num,char* a)

看一个示例:实现atoi()函数 ——字符串与Int类型的转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*-----编译环境VS2019-----*/
#include <iostream>

int my_atoi(const char* str)
{
const char* tmp = str;
int flag = 0;//0表示正数,1表示负数

if (*tmp == '-')
{
flag = 1;
tmp = tmp + 1;//负数从第二个字符开始转化
}
else if(*tmp == '+')
{
tmp = tmp + 1;//带符号的正数也从第二个字符转化
}

int num = 0;

while (*tmp != '\0')
{
num = num * 10 + (*tmp - '0');
tmp++;
}

if (flag == 0)
return num;
else
return (-1) * num;
}

int main()
{
std::cout << my_atoi("+123") << std::endl;
std::cout << my_atoi("-456") << std::endl;
std::cout << my_atoi("789") << std::endl;

return 0;
}

字符串数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#define M 5
#define N 20
int fun(char(* ss)[N], int *n)
{
int i, k = 0, len = N;
for (i = 0; i < ______; i++)
{
len = strlen(ss[i]);
if (i == 0)
*n = len;
if (len ____ * n)
{
*n = len;
k = i;
}
}
return ( _____ );
}
main( )
{
char ss[M][N] = {"shanghai", "guangzhou", "beijing", "tianjing", "chongqing"};
int n, k, i;
printf("\nThe originalb stringsare:\n");
for (i = 0; i < M; i++)
puts(ss[i]);
k = fun(ss, &n);
printf("\nThe length of shortest string is: % d\n", n);
printf("\nThe shortest string is: % s\n", ss[k]);
}

char *c = “agdbh”; 存储的是字符串的首地址吗?

C风格字符数组 p109


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!