导图社区 【 Cxx程序设计教程】第三章 构造数据类型
这是一篇关于【 Cxx程序设计教程】第三章 构造数据类型的思维导图,主要内容有数组、指针、引用、字符串、枚举类型、结构体与共用体等。
编辑于2022-12-25 17:18:05 广东这是一篇关于空间分析与建模的思维导图,主要内容包括:第五章 地理加权回归分析技术,第一章 绪论,题型,第七章 探索性空间分析,第六章 地统计分析,第四章 空间点模式分析,第三章 地理相关性分析,第二章 空间数据分析的基础理论。
遥感科学与技术专业课,高光谱遥感是指用很窄而连续的光谱通道对地物持续遥感成像的技术(多波段目连续→成像光谱遥感)。
中国矿业大学《计算机地图制图》课程期末复习,是以计算机硬件设备为基础,在相应软件系统的支持下,以数字格式对地图制图要素与现象数据进行采集、处理与管理,按照地图制图的规范进行符号化、图版制作与输出,并提供地图自动分析的全过程
社区模板帮助中心,点此进入>>
这是一篇关于空间分析与建模的思维导图,主要内容包括:第五章 地理加权回归分析技术,第一章 绪论,题型,第七章 探索性空间分析,第六章 地统计分析,第四章 空间点模式分析,第三章 地理相关性分析,第二章 空间数据分析的基础理论。
遥感科学与技术专业课,高光谱遥感是指用很窄而连续的光谱通道对地物持续遥感成像的技术(多波段目连续→成像光谱遥感)。
中国矿业大学《计算机地图制图》课程期末复习,是以计算机硬件设备为基础,在相应软件系统的支持下,以数字格式对地图制图要素与现象数据进行采集、处理与管理,按照地图制图的规范进行符号化、图版制作与输出,并提供地图自动分析的全过程
Ch 3 构造数据类型
数组
具有相同数据类型的有序数据的集合
要素
名称、类型、元素、维数、下标
一维数组
声明(定义)
类型名 数组名[ 常量表达式 ];
eg:int a[10]; 表示 a 为整型数组,有10个元素:a[0]...a[9]
注意
数组的大小是通过“[ ]”内的整型常量表达式实现的,且在编译时就已经确定了数组的大小
“[ ]”内必须是常量表达式,不能含有变量
即使先给一个变量赋了初值,也不能出现在“[ ]”内
相同类型的若干变量数组可以在一个类型描述符下一起定义,之间用“ , ”隔开
eg:float x,y,a[10],b[2];
存储
定义了一个数组后,编译系统就为这个数组开辟了一片连续的存储空间,用于存放数组里的所有元素
数组元素在内存中顺次存放,地址是连续的
eg:定义数组double a[10];假设第1个元素a[0]的起始地址是1000号存储单元,那么,
double型数据占用8个字节
最后一个元素
a[9]
最后一个元素的起始地址
1000+(10-1)×8=1036
引用
方法
数组名[下标表达式]
注意
引用数组元素时别“越界”(编译不检查)
若一个数组有n个元素,最后一个元素的下标应该是n-1
初始化
在声明数组时对数组元素赋以初值
方法
全部初始化
int a[5]={66,80,75,92,55};
可省略数组大小
int a[ ]={66,80,75,92,55};
部分初始化
int a[5]={66,80,75};
各数组元素为a[0]=66 a[1]=80 a[2]=75 其余数组默认为0
和循环结合的应用
数据统计,如计算若干个数据的最大值、最小值、总和、平均值、标准差
数学中某些数列问题,如Fibonacci数列
数据的排序
数据的检索,在已排好序的数据系列中查找指定的数据是否存在
二维数组
定义
类型名 数组名[整型常量表达式1][整型常量表达式2];
整型常量表达式1
行下标
整型常量表达式2
列下标
eg:int a[2][3]; 数组a由2 行3列共6个元素组成: a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2]
存储
顺序
先按“行”再按“列”进行存放
在计算机内则为线性
a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2]
引用
方法
数组名[下标表达式1][下标表达式2]
eg:int a[2][3]
注意
引用数组元素时别“越界”(编译不检查)
若一个M行N列数组,最后一个元素的下标应该分别是M-1,N-1
引用不能使用下面的形式:a[1,2]或a(1,2)
初始化
全部元素初始化
按行给二维数组赋初值
int a[2][3]={ {1,3,5}, {6,7,8} };
可简化为:将所有数据写在一个{ }内,按顺序赋值
int a[2][3]={1,3,5,6,7,8};
int a[ ][3]={1,3,5,6,7,8};
可省略第1维的长度,但不能省略第2维的长度!
部分元素初始化
int a[2][3]={{1},{6,7}};
初始化以后的数组元素如下: 1 0 0 6 7 0
表中的花括号不能省略
指针
内存空间的访问方式
通过变量名访问
通过地址访问
指针变量的定义
要说明的问题
指针变量的名字
该变量是一个指针(存储的是一个地址)
这个指针是何种类型的指针(即哪一类型的变量的地址)
类型名 *指针变量名;
类型名
指针所指向的地址中存放的变量的类型,而不是指针本身的类型
一般而言,地址都用long int 型数据表示
对于任何指针变量,它所占的存储空间都是相同的
*
表示紧跟在其后面的变量是指针变量,而不是普通变量
指针的基本操作
让指针指向某个地址
取地址运算符
&
eg:将x的地址赋给p
float x; float *p; p=&x;
可合并为: float x,*p=&x;
指针变量一定要定义并且赋值以后才能使用
指针变量没有赋值前,其值是随机的
这时候的引用是无意义的,更是危险的,可能会破坏操作系统的某个存储单元
若定义了一个指针,但暂时还没有明确的地址指向,可将空指赋给指针变量
p=NULL:或p=0;
访问指针所指向的内容
间接运算符
*
eg:int i(3), *p=&i; 则*p与i的意思相同
取地址运算符“&”和间接运算符“*”是一对互逆运算符
“&”后面跟普通变量
“*”后面跟指针变量
指针的运算
指针赋值
只有同一类型的指针才能相互赋值
eg: float x=1.2, *p1, *p2, *p3; p1=&x; //指针类型与地址类型一致 p2=p1; //同类指针可赋值 p3=0; //空指针 p3=123; //错!
与数组相关的指针
指针 ± 整型表达式
实现指针的移动(数据的移动而非字节的移动)
+后移 -前移
假设int a[5]={1,4,7,2,6}, *p=&a[2]; 那么: p+2指向数组元素6 p-1指向数组元素4
两个指针之间进行减法运算
表示两个指针之间的数据个数
条件
两个指针指向的类型相同
double a[6]={1.1, 2.2, 3.3, 4.4, 5.5, 6.6}; double *p1=a, *p2=&a[4]; 那么,p2 - p1等于4
关系运算
条件
两个指针指向的类型相同
如果有int *p1, *p2; 那么,可以进行关系运算: p1==p2、p1!=p2、p1>p2等
指针与数组的关系
指向数组元素的指针
int x[5]={1,3,4,6,8}, *p;
让p指向数组元素x[0]的方法
p=&x[0];
p=x;
因为在C++中的数组名表示数组的首地址
让指针指向数组元素x[i]的方法
p=&x[i];
用指针引用数组的方法
*(p+i) 或 *(x+i)
p与x是有区别的
p是指针变量
p++,p--出现在赋值符号的左边是允许的
x是数组名,相当于指针常量
x++,x--出现在赋值符号的左边是不允许的
输出一维数组元素的方法
for(int i=0;i<10;i++) cout<<a[i]<<'\t';
for(int i=0;i<10;i++) cout<<*(a+i)<<'\t';
for(int i=0,*p=a;i<10;i++) cout<<*(p+i)<<'\t';
for(int i=0,*p=a;i<10;i++) cout<<p[i]<<'\t';
for(int *p=a;p<a+10;p++) cout<<*p<<'\t';
指针数组
指针数组的所有元素都是指针
定义
类型名 *数组名[整型常量表达式];
指针数组常用于处理多个字符串
动态内存管理
动态申请内存空间,按需分配,灵活方便,不浪费
动态申请空间的进行时间
不是编译时,而是运行时
使用方法
通过指针指向动态申请的空间
三项工作
定义指针变量
动态申请空间——new运算符
动态回收空间——delete运算符
动态内存申请
申请单个变量
类型 *指针; 指针=new 类型(初值);
类型 *指针=new 类型(初值);
int *p; p=new int(5);
int *p=new int(5);
申请一片连续的空间——动态数组
类型 *指针; 指针=new 类型[ 整型表达式];
整型表达式可以是常量或变量
int n; cin>>n; int *p=new float[n];
eg:float *p=new float[N];
二维数组的申请
int (*p)[4]=new int[3][4];
p是指向含有4个元素的一维数组的指针
动态内存回收
用delete释放申请的空间
delete一定与new配对使用
用new申请的空间只能用一次delete来释放
动态空间的释放
释放单个动态变量
delete 指针名;
释放动态数组变量
delete []指针名;
方括号在前,指针名在后
用限定符const修饰指针
为了防止通过指针随意修改变量的值
三种情形
常指针(指针本身是常量)
指针不能修改
int * const p=&x;
const在*后
p是常指针,不许再指向其他变量
p=&y; //错! *p=100; //允许
指向常量的指针(不允许通过指针修改所指向的变量)
int x=1, y; const int *p=&x; (int const *p=&x;)
const在*前
*p=123; //错! x=123; //允许 p=&y; //允许
通过x来修改值不受限制
pd的指向没限制
指向常量的常指针
指针及其所指向的内容都不能修改
int x=1, y; const int *const p=&x; (int const *const p=&x;)
“*”被两个const夹着
p=&y; //错! *p=123; //错! x=123; //允许
引用
概念
给已有的变量起个别名
引用是已有变量的别名,所以不会给它另外分配存储空间
形式
类型名 &别名=已有变量名;
int x=1,y=2; int &r=x; r=y; //正确 int &r=y; //错误!
定义数组的引用
定义整个数组的引用
int a[5]={1,3.,7,9}; int (&ra)[5]=a;
定义某个数组元素的引用
int &r1=a[1];
用途
引用比指针容易理解,少出错
引用常用于函数调用中的参数传递
“引用”能完成“指针”的大部分功能
与指针的区别
指针可以赋空值NULL;引用不允许是空的
指针可“见异思迁”,引用须“从一而终”
字符串
C语言中的字符数组或字符指针
数据类型为字符型(char)的数组称为字符数组
字符数组的定义
char 数组名[整型常量表达式];
eg:char name[10];
字符数组的初始化
花括号内的初始化列表给数组中每个元素逐一赋值
char s[5]={'C','+','+'};
char m[3][3]={{'6','7','2'},{'1','5','9'},{'8','3','4'}};
初始化表中提供的数值少于数组定义额元素个数,剩下的数组为默认值'\0'(空字符)
注意空字符与空格的区别:空格的ASCII值为32,可以在屏幕上输出为数据间的分隔符;空字符的ASCII值为0,不能在屏幕上显示
用字符串常量给字符数组初始化
char s[4]={"C++"};/char s[4]="C++";
s[0]~ s[3]分别存放'C'、'+'、'+'和'\0'
用字符串常量需要占用一个字节来存放字符串结束符'\0'
一个汉字占两个字节
存放n个西文字符一维字符数组至少要定义为n+1个字符
字符数组的赋值与引用
只能对它的元素赋值,不能用赋值语句对整个数组赋值
char s[5]; s={'c','+','+'} //错误 s[0]='C';s[1]='+' //正确
a,b数组已定义为类型和长度的数组,相同类型若b数组已经初始化
a=b; //错误 a[0]=b[0]; //正确
字符数组的输入输出
字符数组元素依次输入输出
通过字符数组名整体输入输出
cout <<字符数组名;
计算机会在输入的字符串的后面自动加上结束标识符“\0”
数组长度大于字符串的实际长度,也只输出到“\0”
如果字符数组中包含多个“\0”则遇到第一个“\0”就结束
cin >>字符数组名;
输出字符,直到遇结束标识符“\0”为止
从键盘输的字符串应短于已定义的字符串数组的长度,否则程序运行出错
输入以空格、回车、Tab键作为结束标志,希望输入的一串字符中包括空格、Tab等字符
通过函数getline输入一整行内容
cin.getline(字符数组名,数组长度,结束符);
结束标记省略,默认值为‘\n’,即按Enter键换行
停止接收字符
输入的字符数超过数组的长度
键盘上输入了与“结束标记”相同的字符
char s[10]; cin.getline(s,sizeof(s)); //当输入字符个数超过s的长度或按回车后输入结束 cin.getline(s,8,'.'); //当输入字符个数超过7个或者遇到字符‘.’时输入结束
字符指针
定义
char *p;
p是一个字符指针
指针表示字符串
将字符指针指向一个字符串常量
char *p=”I love C++”;
将字符指针指向一个字符数组
char s[20]={”I love C++”}; char *p=s;
将字符指针指向动态申请的字符数组
char *p=new char[80];
存储字符串的空间的首地址赋给指针变量,而字符串本身存储在内存储的另一个区域(静态数据区)
字符数组和字符指针的比较
字符数组存储全部字符,而字符指针存储字符串首地址
char s[20]="C++程序设计"; char *p=s; cout<<sizeof(s)<<endl; //数组s定义时的大小为20 cout<<sizeof(p)<<endl; //指针p存放的是地址,占4个字节 cout<<strlen(s)<<endl; //数组s存放的有效字符(不含“\0”)为11(3个西文,4个汉字) cout<<strlen(p)<<endl; //指针p所指向的字符串的实际长度11
初始化以及赋值方式不同
char animal[20]="dog"; //正确! char animal[20]={'d', 'o','g'}; //正确! char animal[20]; animal="dog"; //错误! char *p=new char[20]; p="dog"; //正确!
字符数组必须在定义时整体赋值(一行语句),不能两步(行)赋值
若字符数组在定义时没有初始化,只能对数组元素逐个赋值,而不能对数组整体赋值
指针要有确定的指向——初始化
char str[20],*p; cin>>str; //正确 cin>>p; //编译能通过,但有警告 运行时出错!因为p没有初始化,随机指向某个地址
指针的值可以改变,数组名作为指针常量不能改变
char s[20]="ABC", *p=s; p++; //正确! s++; //错误!
C++新增的string类
定义格式
string 字符串变量名;
eg:string s=″C++ Language″;
定义的同时可以对其初始化
头文件
#include <string>
字符串变量的大小与占用的空间
cout<<sizeof(s)<<endl;---------------------//字符串变量s占用的存储空间字节数——与运行环境有关 cout<<s.length()<<endl;-------------------//字符串变量s所包含的实际字符个数——只有s赋值的字符串长度有关
各种操作
赋值:s1=″How do you do? ″; s2=″Ok! ″
复制: s=s1;
不要求s1、s2长度相同,变量的长度随字符串的长度变化
更改某一字符:string word=''man"; word[1]='e';--------------------//修改序号为1的字符为e,即修改后的word值为men
输入/出: cin>>s;/cout<<s1;
连接: s=s1+s2;--------------------------------------//输出结果为“How do you do?Ok! ”
比较(直接使用条件运算符): (s1 < s2)的值为true
无需使用字符串函数
字符串数组
eg:string BookName[3]={"三国演义","红楼梦","射雕英雄传"};

一个元素——一个字符串变量
每个元素的长度无需一致,且可以变化(元素被赋新值)
枚举类型、结构体与共用体
枚举类型
定义
enum 枚举类型名{枚举元素1,枚举元素2,...,枚举元素n};
说明
eg:enum seasons { Spring, Summer, Autumn, Winter };
enum为关键字
seasons是枚举类型名,不是变量
注意
枚举类型的所有元素要逐一列出
列出的值为一个枚举元素或者枚举常量
枚举元素与一个唯一的int型数对应
一般为:0,1,2,3…的排列顺序
可以人为改动枚举元素对应的整数
eg:enum seasons { Spring=1, Summer, Autumn, Winter };
枚举类型与int型之间的转换
枚举→int 自动转换
eg:enum seasons { Spring=1, Summer, Autumn, Winter }; int n=Autumn;---------------------------------------------//相当于int n=3
int→枚举 强制转换
eg:enum seasons { Spring=1, Summer, Autumn, Winter }; seasons s; s=Summer;------------------------------------//正确 s=2;---------------------------------------------//错误 s=seasons(2);/s=(seasons)2;----------------//正确
枚举变量的输出结果不是枚举元素字面内容,而是它对应的整数值,进行关系比较是也是它们对应的整数参与比较
结构体
一种复合的数据类型,可以把若干不同类型的数据封装在一起,作为一个整体使用
结构体类型的定义
struct 结构体名 { 结构成员描述 };
eg:定义一个通讯录类型
struct AddressList { char name[20]; bool male; short age; char tel[20]; char email[30]; char company[30]; char house[30]; };
结构体类型的变量
定义
eg:AddressList txl;
变量的初始化
AddressList txl={"张三", 1, 20, "13912345678", "zhangsan@163.com", "矿大", "徐州"};
使用
整体操作
同类型的结构体类型的变量之间赋值
eg:t=txl;------------------------------//t中的数据成员与txl中的完全相同
通过成员运算符"."
txl.age=18;--------------------------------//将年龄改为18 strcpy(txl.name,"李四");------------------//修改姓名 cout<<txl.age<<txl.name;-----------------------------//输出年龄和姓名
用途
描述复杂的数据结构
链表,队列,记录;
作为数组元素
AddressList txl[30];-----------------------------//建立一个30名同学的通讯录 cout<<txl[29].name<<txl[]29,tel<<endl;------//输出最后一名同学的姓名和电话号码
指向结构体的指针
AddressList txl={"张三", 1, 20, "13912345678", "zhangsan@163.com", "矿大", "徐州"}; AddressList *p; p=&txl;
通过指针访问结构体成员的两种方法
(*p).成员名
p->成员名
cout<<p-name<<p-age<<endl;
共用体
通过内存覆盖技术,使不同类型的变量共用内存
类型定义格式
union 共用体类型名 { 成员描述; };
注意
占用空间最大的成员作为共用体类型的大小
共用体内的成员是互相排斥的
最后一次给某个成员的赋值,将冲掉之前给其他成员的赋值
共用体内的各成员的起始地址相同
不能对共用体变量初始化
不能对共用体变量整体操作
“*”和 “&“的不同含义