一、字符串与指针
1.字符串
字符串的底层实现是char类型数组,以\0结尾(故判断一个字符串是否结束则判断是否遇到\0),不用担心字符串个数的问题。字符串的底层可以是字符指针,也可以是字符数组。
C++中包含string标准函数库,C中提供cstring标准函数库。使用C的时候在头文件中导入cstring,C++中直接使用string。
注意:在写操作系统层面的函数的时候很多都是用c的标准函数库
string类和java的使用方法类似。定义方式:
//声明构造
string s=“asdfghjkl”;
string s(”asdgfhjkl“);//为了方便,中英文字符可能有错
//读入string对象
cin,cout,getline()
其他使用方法和java类似,不做记录
字符数组和字符指针
按指针定义字符串,可以直接赋值。例如:char *s;s=“hellow world”。还可以写成:char *s=“hellow world”;
按字符数组定义字符串,不能直接赋值。。例如:char s[10];,不能直接赋值,s=“hellowworld”。但是char s[10]=“hellow world”;没问题。
不能把字符串类型赋值给字符类型,反之也不能。要想相互赋值,就需要malloc一个空间,然后进行类型转换。
易错点
对于返回值是指针的函数,所有在局部定义的对象函数结束之后都无效了,所以不能将函数内部的对象作为返回值,不然会报错。(作用域的问题)
2.动态存储管理
目的
静态和自动内存分配管理必须要事先了解数据对象的格式和存储空间的大小。有的场合没法预知大小。
分配方式
C头文件“cstdlib”或“cmalloc”中提供malloc和free操作。
C++使用new和delete提供进行操作
void * 类型
非常重要,但是我不懂。以后遇到再说,这是C中的一些知识,同样对于C中的动态内存分配用法我没有仔细听
注意:在free之后还要对对应的指针赋予NULL值
new\delete
int * p;p=new int; *p=10;
int * p;p=new (int); *p=10;
int * p;p=new int(10);
int * p;p=new (int)(10);
int * p;p=new int[8];//分配8个元素的整数数组
delete p;
delete []p;//销毁的不是指针本身,而是指针指向的新开辟的存储空间
注意:务必记住,有借有还。
所有权与空悬指针
- 指针对指向的目标对象拥有所有权
- 因此在程序中要时刻明确动态内存分配的目标数据对象的所欲权是那个指针。
指针使用原则
- 主动释放。new和delete配对使用
- 所有权转移。在函数结束之前要转移内存的所有权(如果内存需要被保留或者有其他用途的话。),往往通过返回值转移给主要函数
空悬指针
两个指针对象p,q指向new的同一个空间,倘若某个指针p已经free(p);切p=NULL;了。但是另外一个指针没有作此操作。程序结束的时候新开辟的空间操作系统会自动释放,我们还以为q有意义,但是他对应的空间早就没有了,形成了空悬指针。这是个隐含bug。
预防空悬指针办法
- 一个函数中确保一个数据对象的只有一个指针对其有所有权,其他指针即使有权力,只能进行访问,但是不可管理;
- 若新开辟的空间仍然有存在的价值,则需要对所有权进行转移(如何转移所有权?)并且表明什么样的指针有所有权,什么样的没有所有权。
- 在哪儿产生动态内存的分配就在哪儿删除。如果没能删除,那就向上级汇报,逐级汇报。
内存泄漏与垃圾回收
java中不存在内存泄漏,只有new的对象太多的时候才会泄漏,也有相对应的垃圾回收机制(GC),有jvm提供。
内存泄漏:分配了不处理,函数不会处理内存分配,函数结束内存空间依然开辟了,累积的量过多则造成内存泄漏。
二、引用
定义格式:数据类型& 变量名称=被引用变量名称;int a; int &ref=a;
引用性质
- 应用引用类型的变量不占用单独的存储空间
- 和引用对象使用相同的存储空间,相当于给引用对象起别名
- 引用变量必须在定义的时候初始化
- 引用的关联关系在整个生存周期中是不会改变的
常量引用:只能引用,但是不能改变常量的值,即使是参数传递。
引用作为函数返回值时不生成副本
操作符重载的时候引用也很重要
三、散装知识点、问题汇总
1.java中存在\0吗?
2.C++中的exit()是做什么的
函数结束的一个标志之一,传统的结束方式就是return。但是为了平台的兼容性,防止一个进程结束了依然在运行,使用exit()给父进程传递一个消息(其中的参数就是给父进程的),让改进程结束。
3.Makefile又是什么东西?
4.引用和typedef有什么关系?
typedef就是起别名防止出错,而引用是为了改变值
5.为什么要有引用
作为函数参数,应用传递,,直接修改实际参数的值
void Swap(int & x,int y);
此时在其他函数中再调用swap,实际参数的值就会随着形式参数的改变而改变。