引言
我们接着上一章讲,上一章我们说到了二维数组,并用二维数组实现了,对角线的最大值求解,那小伙伴们在深度思考一个问题放在下面,这是老师给我们出的一道思考题,有一定难度,但是对于前边知识都消化的小伙伴们这是肯定没问题的。
请使用二维数组实现如下操作
//某组有5名同学,输入语文和数学成绩,存储后,计算并输出每个同学的总成绩。
答案在最后👇👇👇
哈哈哈哈,有了热身之后,我们接着今天的学习,今天的内容就开始难起来了,除了把剩下的一些有关数组的知识还有就到了我们C++的最重要的指针部分了。好了废话不多说,跟着小杨,开始今天的学习吧!!!
字符数组
- 字符数组可以通过整体引用在cout直接输出内容,直到遇到\0结束输出。
- 字符数组可以使用{}方式初始化或者使用字符串直接进行初始化;
代码参考:
# include <iostream>
using namespace std;
int main()
{
//定义并初始化一个整型变量,并输出,会得到它的内容和位置
int a[5] = {};
cout << a << endl;
//定义并初始化字符数组
char c[5] = { ' ','a','b','v','\0'};//“\0”是作为结束标志。
char d[5] = { ' ','a','b','v','d' };
//最后一个\0是终止符,对于cout的输出,会找到\0才会终止,不然会乱码直到找到\0为止;
//字符数组的整体引用。
cout << c << endl;
cout << d << endl;
return 0;
}
输出显示:
字符串
C++中涉及到的三种字符串的表示方式
- 字符数组的字符串。
- 字符指针的字符串。
- string类型的字符串。
代码展示如下:
// 字符数组字符串
char c1[] = "Hello C++";
cout << "c1: " << c1 << endl;
// 字符指针的字符串
char* p = c1;
cout << "p: " << p << endl;
// string类型的字符串
string s = "Hello !";
cout << s << endl;
// 字符数组字符串是一个包含字符串结束标志的字符数组
char c3[10] = "abc";
cout << "c3: " << c3 << endl;
c3[8] = 'x';
c3[9] = '\0';
cout << "c3: " << c3 << endl;
C++中常用字符串处理函数
- strlen,计算字符串长度。
cout << "strlen(c3): " << strlen(c3) << endl;
- strcpy_s,拷贝字符串。
int main()
{
char c1[4] = "C++";
char c2[] = "abcde"; // c2的长度是6
char c3[10] = "abcde"; // c3的长度是10
/*
strcpy_s(目标字符串,缓冲区大小,源字符串)
缓冲区的大小,大于源字符串的长度,小于等于目标字符串所在数组的长度。
目标字符串所在数组的长度要大于原字符串的长度。
*/
strcpy_s(c2, 4, c1);
cout << "c2: " << c2 << endl;
cout << "c2[4]: " << c2[4] << endl;
strcpy_s(c3, 10, c1);
cout << "c3: " << c3 << endl;
// 常用形式
strcpy_s(c3, strlen(c1) + 1, c1);
cout << "c3: " << c3 << endl;
return 0;
}
- strcat_s,拼接字符串
int main()
{
char c1[20] = "C++ ";
char c2[20] = "program";
/*
strcat(目标字符串,缓冲区,源字符串)
缓冲区 小于等于 目标字符数组的长度,大于 (目标字符串的长度 + 源字符串的长度)。
*/
strcat_s(c1, 12, c2);
cout << "c1: " << c1 << endl;
strcat_s(c1, strlen(c1) + strlen(c2) + 1, c2);
cout << "c1: " << c1 << endl;
return 0;
}
- strlwr_s、strupr_s,转换大小写
int main()
{
char c1[] = "Hello C++ 1@#!";
char c2[] = "Hello C++ 1@#!";
// 转换小写
_strlwr_s(c1);
cout << "c1: " << c1 << endl;
// 转换大写
_strupr_s(c2);
cout << "c2: " << c2 << endl;
return 0;
}
- strcmp,比较字符串
int main()
{
char c1[10] = "abcd";
char c2[20] = "abcd";
char c3[15] = "abce";
/*
strcmp(字符串1,字符串2)
字符串1 == 字符串2 返回0
字符串1 > 字符串2 返回 1
字符串1 < 字符串2 返回 -1
*/
// 字符数组中,字符串结束标志之后的元素不影响比较结果
c1[6] = 'a';
c2[6] = 'b';
int r = strcmp(c1, c2);
cout << "r: " << r << endl;
r = strcmp(c1, c3);
cout << "r: " << r << endl;
r = strcmp(c3, c1);
cout << "r: " << r << endl;
return 0;
}
地址与指针的概念
在讲解地址与指针的概念时,我们应该先学习一下,内存地址的概念
-
内存地址:
- 计算机的内存器被划分成多个存储单元,这些存储单元按照一定的顺序编号,这个编号就存储单元地址,也就是内存地址。
- 地址的编码最基本的单元是字节,每个字节是由8位二进制组成。每个存储单元都有一个唯一的地址,在这个单元中可以存放指定的数据。
-
变量的地址
- 在程序中定义的所有变量,在内存中都要分配相应的存储单元,不同类型的数据所需要的存储空间大小不同。
- 系统分配给变量的内存空间的起始单元地址称为该变量的地址。
- 一个变量地址就称为该变量的指针。
-
指针变量
- 专门用于存储其他变量的指针(即地址)的变量,称为指针变量。
- 指针变量所指向的类型是不能改变的。
- 指针变量必须指向具体内存位置,才可以使用,否则将产生严重的后果。
- 指针运算符
- &取地址,获取变量的地址。
- *解引用,用于获取地址中的内容。
- 算术运算符,+加法、-减法。指针与整数进行加减运算的结果与该指针的类型有关。
代码展示如下:
#include <iostream>
using namespace std;
int main()
{
// 定义整型指针p1
int* p1;
int i = 10;
// &取地址运算符。获取整型变量i的地址并赋值给p1。
p1 = &i; // 也称为p1指向i
cout << "p1: " << p1 << endl;
// *解引用运算符。通过指针访问变量。
*p1 = 100;
cout << "i: " << i << endl;
return 0;
}
- 利用指针做输出最大值
#include <iostream>
using namespace std;
int main()
{
int a = 20, b = 10;
int* p, * p1, * p2;
// p1保存a的地址,p2保存b的地址
p1 = &a;
p2 = &b;
cout << "p1: " << p1 << " p2: " << p2 << endl;
// 如果a大于b,交换p1和p2的地址
if (*p1 > *p2)
{
p = p1;
p1 = p2;
p2 = p;
}
cout << "a: " << a << " b: " << b << endl;
cout << "max: " << *p2 << endl;
return 0;
}
- 算数运算符
#include <iostream>
using namespace std;
int main()
{
// 定义整型数组
int a[5] = { 1, 2, 3, 4, 5 };
// 定义整型指针
int* p = &a[0];
for (int i = 0; i < 5; i++)
{
cout << &a[i] << '\t';
}
cout << endl << "(p + 1): " << (p + 1) << endl;
double a1[5] = { 1.1, 1.1, 1.1, 1.1, 1.1};
double* p1 = &a1[0];
for (int i = 0; i < 5; i++)
{
cout << &a1[i] << '\t';
}
cout << endl << "(p1 + 1): " << (p1 + 1) << endl;
}
习题讲解
有关刚开始的题大家有没有认真思考做出来呢,我这给出不同的两种方案,不过都是异曲同工,都是对不同学科进行分支。好了看代码
代码一:
#include <iostream>
using namespace std;
int main()
{
// 某组有5名同学,输入语文和数学成绩,存储后,计算并输出每个同学的总成绩。
// 定义一个二维数组,一行代表一个同学,一列代表一个学科,总共五个同学,两科单科成绩和总成绩,我们可以定义一个5行3列的数组。
int score[5][3] = {}; //初始化数组并将其全部赋值为零
for (int i=0;i<5;i++) //定义行遍历从每个同学的成绩写起
{
for (int j = 0; j < 2; j++) //定义列遍历,用于输入成绩
{
if (j == 0)
{
cout << "请输入第" << i + 1 << "名同学的语文成绩:";
cin >> score[i][j];
}
else
{
cout << "请输入第" << i + 1 << "名同学的数学成绩:";
cin >> score[i][j];
}
}
score[i][2] = score[i][0] + score[i][1]; //计算总成绩并存储在第三列
cout << "第" << i + 1 << "名同学的总成绩为" << score[i][2] << endl;
}
return 0;
}
代码二:
#include <iostream>
using namespace std;
int main()
{
// 某组有5名同学,输入语文和数学成绩,存储后,计算并输出每个同学的总成绩。
// 定义一个二维数组,一行代表一个同学,一列代表一个学科,总共五个同学,两科单科成绩和总成绩,我们可以定义一个5行3列的数组。
int score[5][3] = {}; //初始化数组并将其全部赋值为零
for (int i = 0; i < 5; i++) //定义行遍历从每个同学的成绩写起
{
int sum = 0;
for (int j = 0; j < 3; j++) //定义列遍历,保证每科成绩都可以录入存储
{
switch (j) //用分支结构来队列进行分支,不同的分支对应的不同学科的成绩
{
case 0: //第一列,语文成绩
cout << "请输入该生的语文成绩:";
cin >> score[i][j];
continue;
case 1: //第二列,数学成绩
cout << "请输入该生的数学成绩:";
cin >> score[i][j];
continue;
case 2: //第三列,总成绩
sum = score[i][0] + score[i][1];
score[i][j] = sum;
break;
}
}
cout << "该生的总成绩为" << score[i][2] << endl;
}
return 0;
}
结语
小伙伴们,指针是比较难的,大家可能只看我敲的代码和讲解把并不能真实的学好,还是要动手敲一敲,加油啊小伙伴们不要放弃。