程序员

c++读书笔记

2020-06-22  本文已影响0人  某昆

c++有很多有意思的小点,今天来记录下这些点

1、字符串

c++中有两类字符串:

c风格字符串的声明也有好几种

char cstr[] = "hellookunu";
char cstr2[] = {'a','b' ,'c' ,'d' ,'e'};
const char* p = "hellochengcheng";

以上三种写法,因为数组名其实就是数组第一个元素的指针,可以认为 cstr&cstr[0] 这两种写法是等价的,所以可以用 char* 来声明字符串。

值得一题的是,在c++中,"hellookunu" 叫字符串常量或字符串字面值,它在c++中存储的格式其实是什么呢?

(const char [11])"hellookunu"

所以,字符串常量真实的存储格式就是c风格字符串,以指针形式存储在内存中,返回的是第一个字符的地址。所以c风格字符串的三种初始化方式是合法的,因为左右两边的类型确实相同。

2、变量声明

c++和java在使用变量之前都必须进行变量声明,但java还要求对变量初始化才可以使用变量。c++也有初始化这个过程,但c++和java在细微之处还是截然不同的。

struct person {
    char name[6];
    int age;
};
person ok;
strcpy(ok.name, "okunu");
ok.age = 1;

注意结构体ok的声明,只声明ok,并没有对ok进行初始化,之后就可以对ok属性赋值了。在java中,这种操作肯定会报错的,必须初始化对象,否则对象为null值,为对象的属性赋值也会报错,因为对象为null。但在c++中是可以的。这就是c++和java的细微差别了。

在c++中,只要为一个对象声明,就会为此对象分配内存了,所以当声明结构体ok时,内存中已经有一块区域属于它了,这块区域内存储着ok的各项属性值,此时当然可以为ok属性赋值。

而在java中,如果只声明一个对象,例如 Person p; java对象的内存分为两块,p这个对象引用存储在栈中,而p所指向的person对象存储在堆中,不过抱歉的是,由于没有通过new操作初始化,p此时所指向的对象为null,故不能对p的属性进行赋值,否则会出现空指针异常。

c++中,如果声明一个指针,例如

person* p;
p->age = 1;

这是一种错误的写法,声明的是指针 p,而不是对象,指针所占用的内存通常是4个字节,声明一个指针后,系统会为指针分配一块内存,用于存储这个指针,但指针所指向的内存区域并没有被分配出来,需要开发者手动分配内存,例如通过 new 关键字来分配内存。

person* p = new person;

person per;
p = &per;

可以通过上述两种方法分配指针所指向的内存区域,这样才算真正地完成了指针地初始化,指针才可以使用,不会报错。值得一提的是,c++中,通过new 分配的内存也是保存在堆中。

分析指针和java的两种使用方法,其实质是一模一样的,java中的对象名,某种程序上就是指针。java号称没有指针,虚拟机自动回收内存,不需要开发者手动来delete内存,但它的实质和c++使用指针一模一样,先为指向对象的指针分配内存,如果开发使用new来初始化对象,则为对象真正地分配内存。

指针写法

指针的格式有很多种,常见的有下几种:

int* pn;  //指向int的指针
int* (*fun)(int *); //函数指针
int** fun(int*); //fun是一个函数,函数返回值为指向int指针的指针
int* (*fun[3])(int*); //数组,数组内的元素是函数指针

指针的写法必须记住了,其实这与 * 的结合律有关系,*它的优先级低于() 也低于 [] ,所以第三行中,fun优先与后边的括号结合,与括号结合,则表明fun是一个函数。

第二行中,用括号将 * 和 fun 括起来,则 fun 优先与*结合,说明 fun 是一个指针,它指向的内容是一个函数

第四行中,fun 优先与 [] 结合,所以fun是一个数组,fun 左边的 * 号则表明,数组中的元素是指针。

指针的写法有很多,还有更多更复杂的,面试这些,我们可以使用typedef来简化它,更多的内容还得用心一一体会才行。

上一篇下一篇

猜你喜欢

热点阅读