第四章 复合类型
2020-02-24 10:42:23 3 举报
AI智能生成
为你推荐
查看更多
C++ plus
作者其他创作
大纲/内容
复合类型
枚举
作用
提供一种创建符号常量的方式,可以代替const
常用来定义相关的符号常量
定义声明
说明
spectrum 被称为枚举
red =0 ....
声明变量
spectrum band;
enum 可省略
变量赋值
band= red;
band = (spectrum) 0;//validband=0;// invalid
变量只有赋值运算,没有算术运算
band 能取的值只能在枚举量中
设置枚举值
指定的值一定要是整型
可以创建多个相同的枚举量
枚举取值范围
例子
bits myflag;myflag = (bits)6; //valid
范围
上限
找到大于这个最大值、最小的2的幂,再-1.
下限
大于o,为0
小于0 ,找到 小于这个最小值的 最大2的幂,+1
bits 上限为16-1=15
其他
枚举量是整型,可被提升为 int 类型
cout<<band; // 结果=3
指针
相关概念不知道的点
*p_updates 是int ,不是指针
char *tax_ptr double *str tax_ptr和str 两个变量本身的长度通常是相同的char 和 double 的地址长度是一样的
int *ptr;ptr 是int 值的地址不说明 ptr 本身的类型是int 值。int 2字节,地址4字节
指针本身也用内存。int *ptr =&a;ptr 、&ptr 都存在且不同
指针的危险
创建指针时,计算机分配存储地址的内存,但不分配用来存储指针所指向的数据的内存。int *ptr;*ptr=23333; 是不可以的。
指针和数字
int *ptr;ptr = 0XB8000000
不能简单地将整数赋值给变量
但可以用强制类型转换ptr =(int *)0XB8000000
new分配内存
指针的真正作用
在运行阶段分配未命名的内存以储存值 int n;int *ptr =&n; 没什么实际意义
分配内存方式
malloc()
new 运算符
更好
格式
int *pn= new int
int *pn;pn=new int ;
原理: new int 告诉 程序需要适合存储int 的内存。new 运算符根据类型确定需要多少字节的内存。它找到这样的内存,并返回给其地址,
这里说pn 指向一个数据对象。 (因为没有内存名称)
两个地方指定数据类型第一个——指针要指向的数据的类型第二个——指定需要什么样的内存
好处
使程序在管理内存方面有更大的控制权
new 分配的内存块和常规声明分配的内存块不同。int a ;int *pa= new int;a——栈的内存区域*pa——堆、自由存储区的内存区域
new 可能会失败。C++提供了检测并处理内存分配失败的工具
delete 释放内存
使用完内存后,归还给内存池,这部分内存可供程序其他部分使用,是有效使用内存的关键。
int *ps =new int ;.....delete ps;
释放ps,但不会删除ps 本身
不能释放已经释放的内存块,不能用delete 释放声明变量的内存
int *ps =new int;delete ps;//okdelete ps://noint a=5;int *pi=&a;free pi; //no
delete 用于new分配的内存。不意味着使用new的指针,而是用于new的地址
int *ps=new int;int *pq=ps;delete ps;//这样可能增加错误地删除同一个内存块两次的可能。
数组指针
指针声明赋值
int a[10];int *ptr ;ptr=a; /ptr = &a[0];
元素表示
a[i];*(a+i);p[i];*(p+i);
new创建动态数组
对大型数据(数组、字符串、结构)使用,是new 和指针的用武之地
静态联编
声明时创建数组,程序在被编译时为它分配内存空间。
要编写程序时指定数组长度
动态联编
用new 和指针程序运行时创建数组。数组称为动态数组,
程序在运行时确定数组长度
创建
int * psome = new int[10];
char * ptr =new char;//就可以了???下面解释:
char *ptr2=new char;cin>>ptr2;cout<<\"the result is:\"<<endl;cout<<ptr2<<endl;结果:输入: i am a student输出: the result is: i
char *ptr2=new char;ptr2=\"i am a student\";//地址已经改变了,其实可以不要上句cout<<\"the result is:\"<<endl;cout<<ptr2<<endl;结果: i am a student
释放动态数组
int *psome =new int [10] ;delete [] psome ;
new 和 delete 规则
元素的使用
数组法
psome[0]、psome[1]
原因:C 和 C++内部都使用指针处理数组
指针法
psome + i
psome +1 后,psome[0] = 原 psome[1];
psome +1 后,最好恢复 psome - 1 后再用delete [] psome;
why ? 不然会出现错误?
指针和数组都可以用这两种方法表示
不能使用 sizeof运算符来确定动态分配的数组包含的字节数,sizeof 不可以
指针、数组和指针算术
指针算术
指针变量+1,增加的值等于指向的类型占用的字节数
指针、数组区别
指针值可改变,但是数组的值不可改变
int a[10];int *p=a;sizeof(a)=4*8=32;//这个时候C++不会把数组名解释为地址。sizeof(p)=4 ;//指针的长度
数组的地址
数组名——第一个元素的地址;对数组名取地址——整个数组的地址
int a[10];cout<<a<<endl;cout<<&a<<end1; 两者值一样。
&a[0] ——4字节的内存块的地址&a——40字节内存块的地址。
a 是一个int 指针。&a 指向包含10个元素的Int 数组可声明初始化这种指针:int (*p)[10] =&a;*p和a等价 (*p)[0]=a[0]
不太明白。。
数组名虽然为第一个元素的地址,但是sizeof ()用于数组名——返回真个数组长度
指针和字符串
原理
在cout 、C++表达式中,char 数组名、char指针以及用引号括起的字符串常量都被解释为字符串第一个字符的地址
字符串的表示
数组
char str[100]=\" \"
char str[100];str[100]=\"i am a student\";
不可以
char *ptr=\"i am\";
char *ptr;ptr=\"i am a student\";
可以,不用分配什么new.
但如果用的是cin>>ptr ;就要new;
“i am a student ”表示的是字符串地址,赋值给了ptr;
string 类
string str1=\"i am \";
string str1;str1=\"i am ...\";
可以直接用cin>>str1;
字符串副本
方法
用new 分配给指针,然后用strcpy赋值;
char *ptr1=\"i am a student\";\tchar *ptr2=new char;ptr2=\"i am a student\"; //改变了ptr2的地址。这样其实不用new 分配/不可以 ,ptr1,ptr2的地址相同
const char *bird = "wern"表示可以用bird表示字符串且不可以改变它。
如果给cout一个指针,将打印地址。但是指针如果是char*则打印字符串,如果想打印char*字符串的地址 :——cout<<(int *)ptr;——cout<<&ptr;//显示的是指针的地址,不是字符串的地址。——cout<<&ptr[0]//显示的是字符串。!!!!
对比字符数组
cout<<str;//字符串cout<<(int*)str;//数组地址cout<<&str;//dittocout<<&str[0];//显示的是字符串!!
有些C++系统,字符串字面值是常量,如果修改,程序运行阶段会错误
int *ptr="i am ";ptr[0]='o';//程序不能运行
int *ptr=new char;
有些系统只使用字符串字面值的一个副本表示程序中多有该字面值
int *ptr1=\"i am a student\";int *ptr2 =\"i am a student\";//cout<<(int *)ptr1; cout<<(int *)ptr2 是一样的;
strcpy原理
strncpy原理
new创建动态结构
单元素
student *ptu=new student;
成员引用
箭头成员运算符
ptu->name;
句点运算符
(*ptu).name
字符串省内存方法
代码
new 和 delete 可以分开使用,但是最好不要
这种方法可以节省内存,但是实际上使用string类更容易
存储类型
依据
分配内存的方法
类型
自动存储
使用范围
函数内部定义的常规变量——自动变量
自动变量
特点
在所属的函数被调用时候自动产生,函数结束时候自动消亡。//自动消亡指的是什么自动消亡???书上说内存自动释放,但是为什么再次用函数的时候,内存还是那个内存???
作用域
包含它的代码块。如果在函数其中的某个代码块定义了一个变量,则变量只在这个代码块上适用。//刷新了我的认识。内存地址还存在吗??
span class=\"Apple-tab-span\" style=\"white-space:pre\
using namespace std;int main(){span class=\"Apple-tab-span\" style=\"white-space:pre\
1.返回str ,返回了地址,但是里面的值消亡。这样是不可以的。
2.第一次第二次存储位置是相同的,所以说虽然值消亡,但是地址没有,还是那个地址???还是说还是分配到了一样的地址???
存储
栈中
静态存储
含义
整个程序执行期间都存在
方式
函数外部声明
在函数内部用static 声明
但是作用域也只在函数内部
初始化
一般实现只能自动初始化静态数组和静态结构
动态存储
new 和delete 运算符
变量特点
节省内存的代码。能在一个函数中分配内存,在一个函数中释放。数据生命周期不完全受程序或函数的生存时间控制
自由存储空间/堆
线程存储(C++11)
内存泄漏
内存被分配出去,无法收回。
应用程序内存被耗尽,出现内存耗尽错误,导致程序崩溃。
分支主题
指向结构体数组的指针
指向结构体的指针数组
指向 指向结构体指针数组 的指针
定义
赋值
表示元素
表示地址???
数组的替代品(先不要深究。。)
模板类 vector
是一种动态数组。可以运行阶段末尾加新数据,可以中间加。是new创建动态数组的代替品。使用内置的new delete 管理内存
使用要求
头文件 vector
名称空间std
声明
vector<int> vi;vector<double>vd(n);
vi 初始化长度为0,其后可以调整。(不知道怎么调整)。
vd(n)中的n ,可以是常量,可以是变量,指明了数组vd 的长度
模板类 array
array
std
元素使用
ai[1]....
可以将array对象赋值给另一个 array 对象。 //数组不可以。vector 也不可以吧
对比
vector功能比数组强大,但效率低。因为n可变??需要长期固定的数组,用数组更好,数组没那么安全和方便。
不知道的点
[]中的指定元素数目,必须是整型常数、const值,也可以是常量表达式。不可以是变量
float loans[20];不能说loans 是数组,而是
字符串最好不写下标,但是其它最好写下标
可以直接 sizeof( int ) ;
c++11初始化
=号可以省略
int a[4] {};
大括号没有东西,初始化为0
禁止缩窄转换
数组的替代品——模板类vector、array
cout 输出
整型数组
结果:输出的是 a的地址
字符数组
结果:abc0贎
字符串
char a[]=\"i am a student\";cout<<a;
结果:i am a student
处理字符串方式
C-风格字符串
基于string 类库
c-风格字符串
性质
以\\0结尾
与字符常量区别
char shirt_size= 'S';
s。。表示的是83
char shirt_size=\"S\"
s 。。即“S”表示的是字符串所在的内存地址,但是这是错误的
输出原理
逐个处理字符串中的字符,直到达到空字符为止
注意
存储字符串的字符数组应该足够大,数组比字符串长的害处只是会浪费一些空间
意思是不会降低处理数组时的效率。?
字符串常量的拼接
原则
任何两个由空白分隔的字符串常量将自动拼接成一个
cout<<\"i am a\" \"student\"
cout<<\"i am a\"\"student\";
结果
字符串之间没有空格
上 :i am astudent
字符串输入
cin 输入字符串
cout<<\"enter your name\\";cin>>name ;cout<<\"enter your favourite food\\";cin>>dessert ;cout<<\"Here is \"<<dessert<<\"for you \"<<name;
cin >> name; 不用读取地址的符号&。
结果:enter your nameAlex bobenter you favourite food Here is bob for you Alex
用空白()确定字符串的结束位置。cin 读取 Alex 后把 bob 留在输入队列中 ,当cin 在输入队列中搜索用户喜欢的甜点时,发现bob ,因此cin 读取bob。
scanf 会 这样子吗??
是
int main(){\t\tusing namespace std;\tchar name[20];\tchar food[20];\tcout<<\"enter your name \\";\tcin>>name;\tcout<<\"enter your favourite food\\";\tcin>>food;\tcout<<\"here some \"<<food<<\" for you \"<<name<<endl;\t\t\tprintf(\"enter your name \\");\tscanf(\"%s\
getline()
类成员函数,能够输入整条字符串,直到换行符
getline()丢弃换行符,空字符来替代换行符
第一个参数name
存储到的数组中的数组名
第二个参数 20
读取的字符数,20——最多读取19个字符数,最后一个\\0
可以进行拼接
cin.getline()完成后返回一个cin对象
get()
类成员函数,能够输入整条字符串,直到换行符
换行符保留在输入序列中
不读取换行符,将其留在输入队列中
第二个get 看到第一个字符是换行符,认为已经达到行尾,不会读取任何内容
变体
cin.get()
读取下一个字符即使是换行符
如果想接收这个字符,应该怎么办???
结果改进应用
get()好处
能知道停止读取的原因是由于已经读取了整行
?? 觉得是getline()也可以
getline()\\get()读取空行
做法
最初,下一条输入语句将在前一条getline()或get()结束读取的位置开始读取。
混合输入字符串和数字
导致的问题
int year ;cout<<\"enter year\"<<endl;cin>>year ;char address[80];cout<<\"enter address\
结果:enter year1999enter addressyear=1999address=
解决方法
cin>>year;cin.get(); / cin.get(ch);
(cin>>year).get(); (cin>>year).get(ch);
string 类简介
用string 类型的变量来存储字符串
提供将字符串作为一种数据类型的表示方法
相关概念
#include<string>
string类位于名称空间std 中,必须使用using 指令,或者std::string 引用
srting 对象就是变量 ,如下的str1
string str1;
= char cha1[ ];
string str1=\"i am a student\";
string str1={\"i am a student\"};
string str1 {\"i am a student\"};
输入赋值
cin>>str ;
一个string对象赋值给另一个string 对象
str1=str2;
直接赋常量
str1=\"i am a student\"
一个一个元素赋值
str1[0]=i;.....
string 的大小能够自动地调整。声明时可以创建一个长度为0的string 对象,输入读取到str1时,会自动的调整长度
再输出的时候会调整吗???会的,会重新调整大小。当作是一个普通变量就可以了。
元素的引用
str[1]...数组表示法一样
字符串合并
str3 = str1 + str2 ;
子主题
str1+=str2;
在字符串str1 后加字符
str1 += \"i am a student\";
与C-风格字符串对比
str1=str2 ;
合并
str1 += str2;
求长度(字符数)
str1.size()
int len1 = str1.size( ); str2.size( );
str1 是一个对象,size()是一个类方法
未被初始化的str对象的长度为0
strlen()
int len2=strlen(charr1)
strlen 原理
从第一个元素开始计算字节数,直至遇到空字符。
比字符数组安全
string类 I/O
getline
一般其它
string
不用说明长度
参数
cin
指出哪里去查找输入
其他形式字符串字面值
一般形式
char charr1[ ]=\" i am a student \".
wchar_tchar16_tchar32_t
wchar_t title = L \" Chief Astrogator \"; = u \" \" =U \" \"
Unicode字符编码方案UTF-8
含义?
根据编码的数字值,字符可能存储为1~4 个八位组
前缀
u8
原始(raw)字符
字符表示的是自己。eg/n 表示的是/和n
R\"( 字符串 )\"
cout<< R\"( Jim \"king\" Tutt uses \"\\" instead of endl. )\"
Jim \"king\" Tutt uses \"\\" instead of endl.
如果要显示 “( 和 )“ 怎么办?
在”和(之间添加其他字符
eg : cout << R\"+*( \"(who woudln`t )\
结果:\"(who woudln`t )\
结构简介
结构定义
main()前面
main()中,紧跟在开始括号的后面
结构变量
地位
是结构数据对象
声明创建
法1
struct student std ;
C++ 中的struct 可以省略
student std;
法2
法3
student std ={ \"wang\
可以没有等号
student std ={\"wang\
初始化为0
student std {};
std.name
可以将string类作为成员
std::string name;
注意名称空间
结构赋值
结构数组
变量创建
初始化变量
inflatable guests[2] ={ {\"ben\
引用成员
结构中的位字段
概念
每个成员称为位字段
格式/例子
struct torgle_register{ unsigned int SN : 4; unsigned int : 4; bool goodIn : 1; bool goodTorgle: 1;};
共用体
union ....{ int int_val; long long_val;};
应用
struct widget{ char brand[20]; int type; union id { long id_num; char id_char[20]; }id_val ;} ;
widget prize;prize.id_val.id_num
struct widget{ char brand[20]; int type; union { long id_num; char id_char[20]; };} ;
pirze.id.num
0 条评论
回复 删除
下一页