最近在leetcode上遇到罗马数字转整数和最长公共长缀这两道题目。涉及到字符串,发现字符串的知识忘光了,就重新学习了一下。
char s[]就是定义一个字符数组。
char s[]="hello";
这时声明的s[]数组有六个元素,除了hello之外还有一个‘\0’。声明函数要传入
char s[]时可以
int RomanToInt(char *s)
也可以
int RomanToInt(char s[])
在函数定义里面可以通过指针s对参数操作,也可以直接用数组下标s[i]。
char *s就是定义一个指针。这个指针指向字符串常量的第一个元素。
char *s="hello";
通过指针访问字符串元素
cout<<*s<<endl;
因为s为"hello"字符串的首地址,*可以取出指针指向的地址里面的内容,所以这时程序打印字符串第一个元素h。
这里有一个问题,通过字符串的首地址,cout<<s<<endl;为什么可以打印出整个字符串?这里我们首先要知道,字符串常量的本质其实就是地址。然后程序在输出字符串时的过程是,从首地址开始逐字节寻址,直到某内存的字节元素为’\0’时才结束寻址,然后输出。我们如果这样输出cout<<s+1<<endl;会发现输出结果变为ello。也就是说首地址变成了指向’e’然后从’e’开始逐字节寻址输出。
在说char **s之前先说说char *s[]。char *s[]指的是定义一个数组,一个元素都是指针的数组。由于指针为指向字符串的收地址,所以char *s[]就是一个存放着多个字符串的数组。例:char *s[] = { “fiower”,“flow”,“flight” };这时而char **s则是一个二级指针。char **s这个char类型二级指针就是专门用来指向char *s[]这种数组。让我们看一下char *s[]里面的内容
char *s[] = { "flower","flow","flight" };
cout << s<< endl;
最后输出00FFFE68。我们可以看到它输出了首地址,说明这个数组里面的元素为地址。如果在前面加*
cout<<*s<<endl;
会看到输出结果为flower。
我们还可以再加一个*
cout<<**s<<endl;
这时会看到输出结果为f。
在看leetcode题解时我发现char *s[]这种数组其实可以用二维数组进行操作。可以看做:
s[6][6]={
'f','l','o','w','e','r'
'f','l','o','w','\0','\0'
'f','l','i','g','h','t'
}
我们可以用输出验证一下cout<<s[0][3]<<endl;这时输出为w。
关于字符串的学习我觉得字符串数组和指针是比较难理解的,建议大家可以自己写写例子然后看看输出结果,这样更有利于理解字符串。