4
abcdef
ef
ghi
《计算机程序设计》
计算机学院计算机研究所编译系统研究室
~/course~/course/main.cppmain.cpp,随堂编程练习的代码请直接在此文件中编辑测一测
判断下列程序的输出
ptrquiz.cpp
敏感词检测
在文字中检测给定的敏感词,分析其出现的位置与次数。
That was yet unnamed warship was built in a Dalian shipyyard next to where the Liaoning is berthed and began a final sea trial in the Bohai Sea on Sunday, heading out to the Yellow Sea. Its design is based on the Liaoning but with a number of modifications.
keyword.cpp
#include <iostream>
#include <cstring>
int main() {
char text[] = "That was ...", keyword[] = "Liaoning";
int count = 0;
char *positions[10];
// ============= begin =============
// 在text中找到keyword所有出现的位置,存放在positions数组中,并统计出现次数存放在count中
// ============= end =============
std::cout << "count = " << count << std::endl;
for (int i = 0; i < count; i++) {
std::cout << "positions[" << i << "] = " << positions[i] << std::endl;
}
return 0;
}学习目标
应用本节知识,解决敏感词分析问题!
考考你
指针的本质是什么?数组名的本质又是什么?二者的区别在哪里?
明察秋毫
指针与数组具有很强的可操作性,在相当程度上具有互换性
arrayasptr.cpp
#include <iostream>
#include <iomanip>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
*arr = -1; // 解引用操作符可以作用于数组名;
std::cout << *arr << std::endl; // 输出-1
int *p = arr; // 数组可以直接赋值给指针,等价于p = &arr[0]
int *q = arr + 1; // 数组名可以与整数进行加减运算(以元素类型为单位),得到新的地址
std::cout << std::boolalpha << (arr == p) << std::endl; // 数组名支持比较运算
return 0;
}[],可看作一个数组的首地址ptrasarray.cpp
明察秋毫
通过索引运算符访问数组元素,等价于对指针进行偏移后解引用。即p[i]等价于*(p + i)
p指向数组a的首元素,p + i等价于a + i,则有以下表达式等价| 表达式 | 等价表达式 | 含义 |
|---|---|---|
p = a |
p = &a[0] |
指针p指向数组a首地址 |
a[i] |
*(p + i) |
数组a的第i个元素,亦即指针p之后的第i个元素 |
*(a + i) |
p[i] |
数组a的第i个元素,亦即指针p之后的第i个元素 |
测一测
已知p和a分别是一个int *指针与一个int数组,下列哪些表达式是合法的?
p = ap = &a[0]a = pp = a+1a = p+1++pa[1] = p[-1]")括起来的字符序列,如"hello world"\n表示换行符\0作为结束标志,额外占一个字节C++字符串在内存中的存储方式
考考你
如果希望在程序中对字符串进行处理,应该将字符串存储在什么结构中?
chararray.cpp
#include <iostream>
using namespace std;
int main() {
char s0[4] = {'a','b','c','d'}; // 使用初始化列表初始化字符数组
char s1[4] = "ef"; // 使用字符串字面量初始化字符数组
char s2[] = "ghi"; // 使用字符串字面量初始化字符数组,长度自动计算
cout << sizeof(s2) << endl;
cout << s0 << endl; // 对于一般类型的数组名(指针),输出的是地址
cout << s1 << endl; // 但对于char数组(指针),输出的是以该地址起始的字符串
cout << s2 << endl;
return 0;
}考考你
s2的长度为4而不是3?0的结果不是abcd?s1[2]和s1[3]的值是什么?chararrayinit.cpp
#include <iostream>
using namespace std;
void printCharArray(char s[], int n) {
for (int i = 0; i < n; i++)
cout << (s[i] ? s[i] : '#') << " ";
cout << endl;
}
int main() {
char s0[4] = {'a', 'b', 'c', 'd'};
char s1[4] = {'a', 'b', 'c'};
char s2[4] = "ef";
char s3[] = "ghi";
// char s4[4] = "jklm"; // 编译错误,试一试!
printCharArray(s0, 4);
printCharArray(s1, 4);
printCharArray(s2, 4);
printCharArray(s3, 4);
return 0;
}考考你
为什么s1采用初始化列表初始化,但尾部却添加了'\0'?
chararray.cpp
#include <iostream>
using namespace std;
int main() {
char s0[4] = {'a','b','c','d'}; // 使用初始化列表初始化字符数组
char s1[4] = "ef"; // 使用字符串字面量初始化字符数组
char s2[] = "ghi"; // 使用字符串字面量初始化字符数组,长度自动计算
cout << sizeof(s2) << endl;
cout << s0 << endl; // 对于一般类型的数组名(指针),输出的是地址
cout << s1 << endl; // 但对于char数组(指针),输出的是以该地址起始的字符串
cout << s2 << endl;
return 0;
}strio.cpp
Hello
0x7ffeab854eb0
字符串、字符数组与字符指针的关系
测一测
<cstring>头文件中| 函数 | 功能 |
|---|---|
strlen(str) |
计算字符串str的长度 |
strcpy(dst, src) |
复制字符串src到字符串dst |
strcat(dst, src) |
追加字符串src到字符串dst尾部 |
strcmp(str1, str2) |
按照字典序比较字符串str1与str2的大小 |
strchr(str, ch) |
在字符串str中查找字符ch |
strstr(str, substr) |
在字符串str中查找子串substr |
strlen求字符串长度str的长度,不包括结尾的空字符考考你
你能否实现自己的strlen函数?
strcpy复制字符串src复制到字符串dest,返回dest
dest与src不能指向同一块内存strcpy,dest必须有足够的空间来保存src,否则会导致缓冲区溢出strncpy最多复制n个字符strcat字符串拼接src追加到字符串dest尾部,返回dest
dest必须有足够的空间来保存src,否则会导致缓冲区溢出strncat与strcat的区别在于,strncat最多复制n个字符strcmp字符串比较str1与str2的大小
str1大于str2str1小于str2strchr字符查找str中查找字符ch,返回第一次出现的位置
nullptrstrchr从前往后查找,strrchr从后往前查找strstr字符串查找str中查找子串substr,返回第一次出现的位置
nullptr<cstring>头文件中| 函数 | 功能 |
|---|---|
strlen(str) |
计算字符串str的长度 |
strcpy(dst, src) |
复制字符串src到字符串dst |
strcat(dst, src) |
追加字符串src到字符串dst尾部 |
strcmp(str1, str2) |
按照字典序比较字符串str1与str2的大小 |
strchr(str, ch) |
在字符串str中查找字符ch |
strstr(str, substr) |
在字符串str中查找子串substr |
敏感词检测
在文字中检测给定的敏感词,分析其出现的位置与次数。
keyword.cpp
#include <cstring>
#include <iostream>
int main() {
char text[] =
"That was yet unnamed warship was built in a Dalian shipyyard next to "
"where the *Liaoning* is berthed and began a final sea trial in the "
"Bohai Sea on Sunday, heading out to the Yellow Sea. Its design is based "
"on the *Liaoning* but with a number of modifications.";
char keyword[] = "Liaoning";
int count = 0;
char *positions[10];
// ============= begin =============
// 在text中找到keyword所有出现的位置,存放在positions数组中,并统计出现次数存放在count中
// ============= end =============
std::cout << "count = " << count << std::endl;
for (int i = 0; i < count; i++) {
std::cout << "positions[" << i << "] = " << positions[i] << std::endl;
}
return 0;
}---
config:
look: handDrawn
themeVariables:
fontSize: 20px
---
mindmap
字符串
指针与数组
数组作为指针
指针作为数组
指针与数组的互换性
字符串
字符数组
字符串
字符指针
字符串函数
strlen
strcpy
strcat
strcmp
strchr
strstr
学习目标
计算机程序设计