C++学习笔记——拾遗

1、指针大小
sizeof(int *)为4,sizeof(float *)为4, sizeof(char *)也为4,存放地址4个字节就够了,int、float、char指的是地址上的数据的类型。

2、空指针,如int * buf = NULL
空指针指向内存编号为0x00000000的地方,此处是不可以读写的,一般用于指针初始化。其实0x00000000~0x000000FF之间的内存都是系统占用的,都不可以读写。

3、野指针,如int * buf=(int *)0x00001100
0x00001100这个地址我们不认识,如此赋值可能导致程序运行异常。空指针和野指针都不是我们申请的空间,因此不要访问。

4、常量指针,如int a=10; int b=10; const int * p = &a; p=&b;
指针的指向可以修改,但指针指向的值不可以修改。

5、指针常量,如int a=10; int * const p = &a; *p=20;
指针的指向不可以修改,但指针指向的值可以修改。

6、修饰常量,如int a=10; const int * const p = &a;
指针的指向不可以修改,指针指向的值也不可以修改。

7、结构体
结构体,自建数据类型,如学生数据类型

struct student{
string name;
int age;
int score;
}s3;

// 方式1,类似于int a;a=3;
student s1;
s1.name = "张三";
s1.age = 28;
s1.score = 98;

// 方式2,类似于int a=3;
student s2={"李四",29,99};

// 方式3
s3.name = "王五";
s3.age = 30;
s3.score = 100;

// 结构体指针,类似于int a;a=3;int *p=&a;
student *p1 = &s1;
cout<<p1->name<<p1->age<<p1->score<<endl;

8、结构体嵌套结构体

# include <iostream>
# include <string>
using namespace std;

struct student
{
	string name;
	int age;
	int score;
};

struct teacher
{
	string name;
	int age;
	student stu;
};

int main(){
	teacher t;
	t.name = "老王";
	t.age = 50;
	t.stu.name = "小王";
	t.stu.age = 20;
	t.stu.score = 100;

	cout << t.name << "   " << t.age << "   " << t.stu.name << "   " << t.stu.age << "   " << t.stu.score << endl;

	// 命令行窗口不要关闭
	system("pause");

	return 0;
}

9、形参与实参
定义函数时,括号里的参数是形参,调用函数时,括号里的参数是实参。不管传递值还是传递地址,形参都是实参的复制,当实参很大很大时,如一个学校全体学生的数据,复制一个同样大小的形参,电脑内存可能溢出,如果传递地址,则只需要4个字节的空间,显然更好。但也要注意,传递地址时地址上的数据可能在子函数中被无意篡改,为了预防这个隐患,形参可以使用常量指针。

10、随机数

srand((unsigned int)time(NULL));//随机数种子
int random = rand()%21+80; //80~100

11、全局区
写在函数体外面的变量是全局变量。
在全局变量前面加上const就是全局常量。
在局部变量前面加上static就是静态变量。
全局变量、全局常量、静态变量存放在全局区。
全局区的数据在程序执行结束后自动释放。

12、栈区
写在函数体里面的变量是局部变量。
在局部变量前面加上const就是局部常量。
局部变量、局部常量存放在栈区。
栈区的数据在函数执行结束后自动释放,所以函数不要返回局部变量或局部常量的地址,因为这样得不到我们想要的数据。

13、堆区
new创建的数据存放在堆区,并返回一个地址,如int *p = new int(10);int* arr = new int[10];
堆区的数据由程序员释放,如delete p;delete[] arr;,如果程序员没有释放,在程序执行结束后自动释放。

14、引用
引用的作用是给变量起别名。
引用必须初始化,初始化之后不可以更改。
不能返回局部变量引用。
如果函数的返回值是引用,那么这个函数调用可以作为左值。
引用本质上是一个指针常量。
常量引用本质上是一个修饰常量。

int a =10;
int &b = a;
b = 20;
cout<<a<<endl;//结果为20
# include <iostream>
# include <string>
using namespace std;

int& test()
{
	//不能返回局部变量引用,所以需要定义为静态变量
	static int a = 10;
	return a;
}

int main(){
	int &b = test();
	cout << b << endl;//结果为10
	cout << b << endl;//结果为10

	test() = 1000;

	cout << b << endl;//结果为1000
	cout << b << endl;//结果为1000

	// 命令行窗口不要关闭
	system("pause");

	return 0;
}
# include <iostream>
# include <string>
using namespace std;

void show(const int & val)
{
	// val = 1000;//不允许修改常量引用的值
	cout << val << endl;//结果是10
}

int main(){
	int a = 10;
	show(a);

	// 命令行窗口不要关闭
	system("pause");

	return 0;
}

15、万事万物皆为对象,对象有其属性和行为。具有相同性质的对象可以抽象称为类。

16、构造函数:主要作用在于创建对象时为对象的成员属性赋值,由编译器自动调用,无需手动调用。
析构函数:主要作用在于对象销毁前执行一些清理工作,由编译器自动调用,无需手动调用。

# include <iostream>
# include <string>
using namespace std;

class Person
{
public:
	Person()
	{
		cout << "Person的无参构造函数" << endl;
	}

	Person(int age, int height)
	{
		m_age = age;
		m_height = new int(height);
		cout << "Person的有参构造函数" << endl;
	}

	Person(const Person &p)
	{
		m_age = p.m_age;
		m_height = new int(*p.m_height);
		cout << "Person的拷贝构造函数" << endl;
	}

	~Person()
	{
		delete m_height;
		cout << "Person的析构函数" << endl;
	}

	int m_age;
	int * m_height;
};

void test()
{
	Person p1;
	Person p2(10, 160);
	Person p3(p2);
	cout << "p3.m_age = " << p3.m_age << "   *p3.m_height = " << *p3.m_height << endl;
}

int main(){
	test();

	// 命令行窗口不要关闭
	system("pause");

	return 0;
}

在这里插入图片描述

17、默认情况下,C++编译器至少给一个类提供3个函数:
(1)默认无参构造函数,函数体为空;
(2)默认拷贝构造函数,对属性进行值拷贝;
(3)默认析构函数,函数体为空;
如果用户定义有参构造函数,C++不再提供无参构造函数;
如果用户定义拷贝构造函数,C++不再提供无参构造函数,也不再提供有参构造函数;

18、静态变量与静态函数

# include <iostream>
# include <string>
using namespace std;

class Person
{
public:
	static void fun()
	{
		m_A = 200;
		// m_B = 200; 静态函数只能调用静态变量
	}

	static int m_A;
	int m_B;
};

// 静态变量在类外初始化
int Person::m_A = 100;

void test()
{
	Person p1;
	cout << "p1.m_A=" << p1.m_A << endl; //100
	cout << "Person::m_A=" << Person::m_A << endl; //100

	p1.fun(); // 对象调用静态函数
	Person::fun(); // 类调用静态函数
	cout << "p1.m_A=" << p1.m_A << endl; //200
	cout << "Person::m_A=" << Person::m_A << endl; //200

	Person p2;
	p2.m_A = 300; // 所有对象共用静态变量
	cout << "p1.m_A=" << p1.m_A << endl; //300
	cout << "Person::m_A=" << Person::m_A << endl; //300

}

int main(){
	test();

	// 命令行窗口不要关闭
	system("pause");

	return 0;
}

19、只有非静态成员变量属于类的对象上

# include <iostream>
# include <string>
using namespace std;

class Person
{
public:
	int m_A;                              //非静态成员变量 属于 类的对象上
	static int m_B;                       //静态成员变量 不属于 类的对象上
	int get_A(){ return m_A; }            //非静态成员函数 不属于 类的对象上
	static int get_B(){ return m_B; }     //静态成员函数 不属于 类的对象上
};
int Person::m_B = 0;

void test()
{
	Person p;
	cout << "sizeof(p)=" << sizeof(p) << endl; //sizeof(p)=4
}

int main(){
	test();

	// 命令行窗口不要关闭
	system("pause");

	return 0;
}

20、this指针指向被调用的成员函数所属的对象

# include <iostream>
# include <string>
using namespace std;

class Person
{
public:
	Person(int age)
	{
		this->age = age; //this指针指向被调用的成员函数所属的对象
		//m_age = age;
	}

	Person& PersonAddAge(Person p) // 返回的是对象的引用,不会重新创建一个对象
	{
		this->age += p.age;
		return *this; // *this为被调用的成员函数所属的对象
	}

	int age;
	//int m_age;
};

void test()
{
	Person p1(10);
	Person p2(10);
	cout << "p1.age=" << p1.age << endl; // p1.age=10
	cout << "p2.age=" << p2.age << endl; // p2.age=10
	p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
	cout << "链式调用后p2.age=" << p2.age << endl; // p2.age=40
	
}

int main(){
	test();

	// 命令行窗口不要关闭
	system("pause");

	return 0;
}

21、常对象与常函数

# include <iostream>
# include <string>
using namespace std;

class Person
{
public:
	void fun()
	{
		m_A = 100;
	}

	// this指针的本质是指针常量,类似于Person * const this
	// 在成员函数后面加上const,this指针的本质就是修饰指针,类似于const Person * const this
	void showPerson() const //常函数
	{
		// this = NULL; // this指针的指向不可以修改
		// this->m_A = 100; // this指针指向的值不可以修改
		this->m_B = 100;
	}
	int m_A;
	mutable int m_B; // 特殊变量,在常函数中可以修改
};

void test()
{
	const Person p; // 常对象
	// p.fun(); // 常对象只能调用常函数
	p.showPerson();
}

int main(){
	test();

	// 命令行窗口不要关闭
	system("pause");

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值