经过上学期对《c语言程序设计》的学习,对于c语言基础的入门知识已经掌握。到了下学期新的知识也比上学期的学习难度更高,我们需要更加的深入学习c语言的知识与技术。
首先接触到的是“复合类型”专题,这个专题主要讲的是c语言的内置复合类型有:指针,引用,数组,结构体,联合,枚举等。
在本章的最开始,老师也向我们介绍了些C++11的内容。
1.constexpr对象。
在认定一个对象为常量时,我们可以将其定义为constexpr类型,其返回值一定为常量。编译器在验证对象是否为常量表达式时,通过constexpr可以获得编译时的常量。还有一点constexpr在使用上和const没有区别。
2.auto类型说明符。
在写程序的过程中有时需要将一个表达式赋值给变量,但前提必须是知道表达式的数据类型,在变量前加上auto类型说明符,系统自动识别其数据类型。
3.declcype类型指示符。
declcype类型指示符的作用是选择并返回操作数的类型。
在我们日常的学习或者编写程序时,当希望从初始值表达式中推出定义变量的数据类型,可以使用auto类型说明符。在希望用表达式推出要定义的变量类型,但不想用这个表达式的值初始化该变量时,可以使用declcype类型指示符。
4.range-for语句。
这是一种简化的for语句,用处也是对某个序列或容器进行某个操作。
range-for的基本格式为 range-for(declaration:expression)statement;
declaration:定义一个变量,表示序列中的每个元素。
expression:需要被执行操作的序列或数组。
statement:序列或数组被执行的操作,通常为一条语句或语句块。
以上是新增的C++11的内容。
第一个介绍的是“指针与引用”
讲到这个首先了解的应该是内存地址,在日常学习中,自己编写的代码,还有用于测试的数据都需要储存在内存中。在我们需要访问内存地址时,一般有两种方法。一是通过名字直接访问,二是使用内存地址访问 这个称作间接访问。
指针持有一个对象的地址,也称为指针指向这个对象。通过指针也可以间接访问操作所指向的对象。
基本格式为:类型*指针变量
int ival=120;
int *pi=&ival;
这样以来pi中存放的便是ival的地址,&为取地址符,在接下来的程序中,一旦涉及到*pi,直接可以将其看做ival来使用。
指针不能保存非地址值,也不能被赋值或初始化为不同类型。
当指针值为0的时候,则表示的是一个空指针,不指向任何对象的指针。
将指针变为空指针有以下方法:
int *pi=nullptr int *pi2=0 #include<cstdlib>int *pi3=NULL;
注意 不能对空指针解引用。
指针也可以进行自增或自减操作,例如:
int *pi=&a; char*pi2=&ch;
pi++; pi2++;
这里pi是在原地址加4,pi2在原地址加1.因为int类型是占4个字节 而char类型是占1个字节。
c++中还有一个通用指针:void。它可以持有任何类型的地址,它只能表明为相关的地址,但这个地址储存的对象并不知道,所以不能通过void指正访问该指针指向的对象,只能用于传输地址。
编译器在处理程序源代码时分配内存,可以静态分配内存也可以动态分配内存。
静态和动态差别主要是:
静态对象是有名字的对象,可以直接对其操作,动态则是相反,没有名字需要通过指针间接对其操作,静态对象的空间分配有编译器自动处理,动态对象的空间分配必须由操作人自主管理。
所以我们将用到new和delete这两个相对的运算符。
new的作用是:在堆上动态分配空间,创建对象,并返回对象的地址。有三种基本表达形式:
new 类型 或 new类型(初始值) new类型【数组大小】 new(指针)类型;
第一个用于分配当个对象,并返回其地址。
第二个是在堆上分配指定类型和大小的数组,并返回数组首地址。
第三个是定位new在指针指向的空间中创建一个指定类型的对象。程序员预先分配大量内存,通过定位new表达式在这段内存中创建对象。
这个是 new 类型 或 new 类型(初始值)的注意事项。
这是new 类型[数组大小]的例子。
这是new 指针(类型)的例子和注释。
delete运算符
堆上的空间在使用后必须释放,否则会导致内存泄漏(动态内存空间使用后为释放,一直被占用),delete运算符便是用来释放被占用的内存。
释放new分配的单个对象的delete形式: delete 指针;
释放new分配的数组的delete形式:delete[ ]指针;
执行delete运算后指针所指向的空间被释放,不能再使用指针所指向的内容,但这个指针自己的存储空间不受影响。
delete运算符执行后的指针为空悬指针,指向不确定的单元,使用这个单元是非法的,可能会引起不可预料的错误。
“引用”
通过引用可以间接操控对象,在程序中,引用主要用作函数的参数
引用的定义和初始化
引用由类型标识符和一个取地址符(&)来定义
type& refVariable = leftValue;
引用必须被初始化,初始值是一个有内存地址的对象
例如:
int x=100,y=20;
int &r=x;
这里r就是x的引用。需要注意的是 引用一旦初始化,就不能再绑定到其他对象上,对引用的所有操作都会应用到它所绑定的对象上。
使用左值引用时注意
引用并非对象,是为已存在的对象所起的另一个名字
引用只能绑定到对象(有内存地址)上,不能与字面值或某个表达式的计算结果绑定在一起
引用本身不是对象,所以不能定义引用的引用
我们还得注意的是与引用差不多的指针。来稍微分析一下他两的区别:
指针保存的是对象的地址,引用则是直接指向这个对象。
指针是通过*号间接访问对象,引用是对象的别名,可直接访问。
指针可以不指向对象他的值为零,引用必须要指向一个对象,不存在空引用。
指针之间相互赋值会改变指向关系,引用之间赋值只是他们所指向的对象之间相互赋值。
右值引用(简述)
右值引用的基本语法是type&&引用名=右值表达式;
右值引用在企业开发人员在代码优化方面会用到。右值引用中“&&”中间不能有空格。
const限定指针
如果在写代码过程中,我们不希望某个值或者某个地址在中途被改变,const限定指针便起到了这个作用。
注意!:
我们可以将一个非const地址赋值给一个const指针。但不能将一个const地址赋值给一个非const指针。
例如:
int ival=1;const int *pi=ival//这是正确的;
const int ival2=2; int *pi2=ival2;//这是错误的;
const int ival3=3;const int *pi3=ival3;//这是正确的;
const与左值引用。
const引用可以绑定在const对象上。不能用非const引用指向const对象。
结构体。
结构体是把一组来自不同类型数据组合在一起构成复合类型,每个数据都是结构体的成员。结构体由关键字struct定义。
基本语法形式:
struct 结构体类型名{
成员声明}
这个常常用于数据统计或者计算,结构体的成员不能单独使用,必须由结构体类型通过选择运算符“.”来选择。
枚举类型定义一组命名整数常量,提高代码可读性。
begin(数值名)作用是返回数组第一个元素的指针 end(数组名)返回的是指向数组最后一个元素的下一个位置的指针。
标准库类型string
标准库类型string表示可变长度的字符序列,string可以支持各种初始化方式:默认初始化,拷贝初始化,直接初始化等。使用string时,需要添加头文件:#include<iostream>;string也支持字符串之间的复制,比较,连接。
定义和初始化string对象方式有:
。
string的常用操作:
。
我们写代码最经常遇到的标准库iostream中,可以直接读写string对象。
在读写string对象时,大多使用的时getline函数:
其中包含两个参数:输入流对象和存放字符串的string对象,从指定输入流中读取内容直到换行符,将所读内容存入string对象。
判断sring对象是否为空可以使用empty()函数。
判断sring对象的长度用到size()函数
标准库类型vector。
vector可以看做一个容器,里面容纳着对象,它与数组对比起来看更灵活,更方便,是长度可变的数组。要使用vector要包含头文件<vector>.
定义vector数组时必须指定元素类型,格式是:
vector<元素类型>变量名
vector是动态变化的,可以在初始化的时候指定vector对象的大小和初始值。
大多的操作现在不做介绍,主要介绍push_back()和pop_back()。
push_back()的作用是将一个值添加到vector的末尾。
pop_back()的作用是删除对象末尾的对象。
自我感觉在vector这个专题有几个需要注意的事项:
我们在使用pop_back()删除对象时,需要先检查是否为空,可能会引起错误。
在给vector添加对象时,不能用到for语句,用的是push_back()。
在前段时间,我们接到一个作业:给我们成绩让我们计算总分和绩点。
这次作业中,我们就用到了string序列,结构体struct,结构体数组等,还用到bool重新定义排序,使其从大到小排序,这个是请教同学才会的。也有很多需要注意的地方,例如访问结构体成员要用到下标“.”等
文件流输入输出。
在作这个成绩表作业之后,老师给我们提出了是否可以直接将文件中的数据引入程序的问题,让我们去试一试。虽然最后还是没有成功,但也自己总结了一些知识点:
将标准输入,标准输出与命名文件关联起来:
c:\>program_<inputfile>outputfile.//运行名为program.exe的文件。
c++标准库中的文件流。
ifstream:用于输入文件。
ofstream:用于输出文件。
fstream:把文件连接到流对象用来输入和输出。
关闭文件流:使用close函数。
其他较复杂的内容就先不介绍了。
函数。
函数在上学期便有接触,基本的知识和内容已经了解,在此就不和大家一一介绍了。
在此稍微介绍新学内容:
参数传递实质可以分为传数值和传地址两种。
传数值是把实参的值复制到形参的存储区,即实际参数初始化。
传地址是把地址拷贝给形参。
传引用则是:函数接受的是实参的左值,函数操控的是实参的别名,可以改变实参的值。
函数调用。
函数调用会使程序的主动权转移给被调用函数,之前的函数活动会暂时停止。被调用函数执行结束后,程序控制权又回到主调函数,在执行中如果遇到return语句,则直接返回。
按值传递参数的特点:不会直接改变实参的内容,简单直接。
重载函数。
重载函数指的是名字相同但实参类型不同,函数本身的功能不同,这称为重载函数。在输入时不需要特意说明,直接输入编译器会自动识别并调用相对应的函数。
返回类型和return语句。
return语句上面已经大体介绍过了,结束当前函数,将控制权调回主调函数。
void返回的是无类型的。
以上是对函数和复合类型的知识摘要和自我理解,如有错误或表达不当,请大家多多指出。