22 地址与指针
小作业:
实现一个函数,作用是获取一个数组中的最大值和最小值,函数声明如下:
void get_min_max(int src[], int* max_v, int* min_v)
{
//函数代码写在这个下面
}
23 数组与指针
C/C++中规定数组名字就是数组的首地址。注意,是数组的首地址,也就是数组的第0个元素的地址
用指针操作字符串数组:
定义两个字符数组输入如下:
char str1[50] = {0}, str2[] = “I Love cctry.com!”;
用指针的方式,实现将 str2 拷贝到 str1 中。
char str1[50] = {0}, str2[] = "I Love cctry.com!";
char* pstr1 = str1, *pstr2 = str2;
int str2len = strlen(str2);
for (int i = 0; i < str2len; i++)
{
//pstr1[i] = pstr2[i]; //方法一
*(pstr1++) = *(pstr2++); //方法二
}
//以下是方法三:
/*for(; *pstr2 != 0 ;)
{
*(pstr1++) = *(pstr2++);
}*/
小作业:
输入一个字符串,例如:
a123x456__17960?302ab5876
将其中连续的数字作为一个整数,依次存放到一个数组a中,例如:123放在a[0]中,456放在a[1]中。统计共有多少个整数,并输出这些整数。
#include <iostream>
#include <string>
using namespace std;
int main()
{
char str[100] = { 0 };
int a[100] = { 0 };
int t,j=0;
cin >> str;
int len = strlen(str);
int count,num,flag=1;
for (int i = 0; i < len; i++)
{
if (str[i] >= '0' && str[i] <= '9')
{
t = str[i] - '0';
if (str[i-1] >= '0' && str[i-1] <= '9')
{
count = 10;
num = num * count + t;
}
else
{
count = 1;
num = t;
}
if (str[i + 1] >= '0' && str[i + 1] <= '9')
flag = 0;
else
flag = 1;
if (flag == 1)
{
a[j] = num;
j++;
}
}
}
for (int i = 0; i < j; i++)
{
cout << a[i] << " " << endl;
}
return 0;
}
24 结构体类型
结构体类型的声明:
struct 结构体类型名
{
//成员表;
};
例:
struct Student
{
string name;
int num;
char sex;
int age;
};
定义结构体类型变量:
例:
Student zhangsan, lisi;
初始化:
例:
Student zhangsan = {"张三", 1001, 'm', 25};
备注:初始化参数的顺序一定要和结构体类型声明的成员表顺序一致才行,不然会报错而且会错误的赋值。
初始化一部分不初始化一部分的,不初始化的部分就默认为0;但完全没有初始化的,是乱码
结构体类型变量成员的访问:
结构体变量名.成员名
例:
zhangsan.num = 29;
25 结构体数组与指针
1、结构体类型和数组配合使用
2、结构体变量作为函数参数:
默认情况下是以值传递的方式
3、指向结构体变量的指针:
Student stu;
Student* pstu = &stu;
(*pstu).num = 102;
更简单的方法:
Student stu;
Student* pstu = &stu;
pstu->num = 102;
小作业:
①、根据运算符的优先级,大家想一下:
Student stu[2] =
{
{ "aaa", 0, 'f', 10 },
{ "bbb", 0, 'm', 12 }
};
Student* pstu = stu;
++pstu->num = 202; //这句代码执行之后,到底是stu[0] 的 num 值变化了,还是 stu[1] 的 num 值变化了?
是stu[0]
26 枚举类型及定义新的类型名字
枚举类型的声明:
声明枚举类型用 enum 开头,例如:
enum ESex
{
ESex_Male, //男性 注意是逗号分隔
ESex_FMale //女性 注意没有符号结束
//以上称为枚举元素或枚举常量
};
枚举元素是常量,所以不能对他修改值,但是可以初始化
如果没有初始化,默认值是从上到下从0往下+1
但是不是按顺序+1,是在上一个的基础上+1,如下例:
最后一个如果按顺序加,应该是4,但它是6,5+1得来的
用 typedef 类型声明新的类型名字:
使用 typedef 声明一个新的类型名字来代替已有的类型名。注意是新的类型名字,只是名字而已,不是一种全新的类型,只是改个名字而已。
例:
无符号的整型int变量 unsigned int 太长,就可以像以下这样:
typedef unsigned int uint;
uint a = 5;
3
27 引用及new和delete的使用
引用
C语言中没有引用,C++有引用
变量的引用就是一个变量的别名,变量和变量的引用代表着同一个变量。
例:
int a = 5; //语句1
int& b = a; //语句2 这个是引用
int* p = &a; //语句3 这个是取地址
记住:紧跟在数据类型后面的&符号就是引用的声明符号,其他情况都可以认为是取地址符号。
① 必须先定义一个变量,之后对该变量建立一个引用。
(类比寄生虫,总之就是引用不能独立存在,也不可能定义一个引用,只有声明引用)
② 声明一个引用时,必须同时对其初始化,即声明该引用代表哪一个变量。(作为函数形参例外)
③ 声明一个引用后,不能再让其作为另一个变量的引用了。
④ 不能建立引用数组
⑤ 可以建立引用的引用,也可以建立引用的指针
引用的本质还是指针,只不过指向不能改变,只能指向一个指定的变量
new和delete
在以后的开发过程中,因为局部变量的局限性,只能在其作用域内使用。因此,我们需要动态的分配和撤销内存空间,使其可以在任何函数中使用。
new 出来的变量/内存的生命周期:不主动 delete的话会一直存在,直到进程结束
new 和 delete 的使用:
例:
int* p = new int(2);
//申请了一个int类型的变量,初始化值为2,之后new操作符会返回一个指针,把这个int类型指针赋给p。那么p指向的变量的值就为2
Student* pStu = new Student{ "aa", 001, m, 21 };
//像这种结构体的,初始化用大括号
记住:new完返回的是指针,所以要用一个指针来接收
new数组:
例:
int* p1 = new int[10]; //new一个有10个int型变量的数组
p1[0] = 2;
p1[1] = 3; //通过p1给数组赋值
delete[] p1; //删除,注意要加一个中括号
小作业:
char* get_same_string(char* p1, char* p2)
{
//
}
get_same_string 函数的作用是从参数p1和p2中找出相同的部分,例如,p1的内容是:“aabbcc”,p2的内容是:“kkbcyy”,他们相同的子串就是 “bc” 。
完成 get_same_string 函数的功能
#include <iostream>
#include <string>
using namespace std;
int m;
char* get_same_string(char* p1, char* p2)
{
int len1 = strlen(p1);
int len2 = strlen(p2);
char t[100][100] = {0}; //以一个二维数组作为标记计数,按对角线斜下方向,有相同的+1,
char* same = new char(0);
for (int i = 0; i < len1; i++)
{
for (int j = 0; j < len2; j++)
{
if (p1[i] == p2[j])
{
t[i][j] = 1 + t[i-1][j-1];
}
}
}
m = t[0][0];
int a, b;
for (int i = 0; i < len1; i++) //找二维数组中的最大值
{
for (int j = 0; j < len2; j++)
{
if (t[i][j] > m) {
m = t[i][j];
a = i;
b = j;
}
}
}
for (int i = (m); i > 0; i--) //按在二维数组的计数,按对角线斜上方向倒推,记出对应的字符
{ //因为是倒推,所以放进数组记录时也是倒回来放
if (t[a][b] != 0)
{
same[i - 1] = p1[a];
a--;
b--;
}
}
return same;
}
int main()
{
char* p1 = new char;
char* p2 = new char;
char* p3 = new char(0);
cin >> p1 >> p2;
p3 = get_same_string(p1, p2);
for (int i=0; i<(m); i++)
{
cout << p3[i];
}
cout<<endl;
return 0;
}
28 VS编程实用技巧
清理工程源码,删除无用文件,减少工程体积:
①、工程目录下的Debug/Release文件夹都可以删除,包括两层结构;
②、工程目录下的:SolutionName.sdf、ipch文件夹 以及 *.pch 等文件都可以直接删除
③、如果不想让VS在工程目录中生成②的文件,可以按照如下设置:
工具(T)->选项(O)…->文本编辑器->C/C+±>高级->回退位置->
始终使用回退位置->True
回退位置已在使用时,不警告->True
回退位置->留空
经过以上设置之后,VS会把 sdf、pch 等相关文件生成在系统的临时目录中,从而不生成在工程目录中,所以以后打包的时候就方便了,不用每次都清理。