朝花夕拾--C++再学习

一,寻址

  1. 通过变量名
  2. 通过内存地址

取地址运算符&,用来获得变量的地址.

void getAddress() {
	int var;
	cout<<"var address is: "<<&var<<endl;
}

输出结果是:var address is: 0x7ffcf4dd4e14

为何这里是12位的16进制呢,换成2进制就是48位,难道我的机器不是64位机吗? 

二,对齐

内存对齐,文件对齐

程序在编译链接后会被分割成一个个区块,而区块在内存和文件中按照一定的规律对齐.

//32位系统内存对齐值是:1000H == 4KB
//64位系统内存对齐值是:2000H == 8KB
//文件对齐值是:200H  

操作系统处理内存时内存页是4KB

https://blog.csdn.net/zyq522376829/article/details/46357691 

三,指针

既然指针变量存放的是一个地址,而32位系统的地址都是4个字节,为什么不用一个整型变量来存储而要发明指针呢?

如何根据指针变量来获取指针所存地址对应的值?--Deference(解引用),即在指针变量前加*号.

如std::cout<<*aPtr<<endl;

因此1,变量a和a的指针aPtr,代表同一个值,即a == *aPtr;

因此2,*aPtr = -100,将会修改a的值.

(1) *的两种用途:

1. 用于创建指针

int *mPtr = &myInt;

2. 对指针进行解引用

*mPtr = 123456;

(2) 指针与数组

数组的名字就是一个指针,它指向数组的基地址(也就是第一个元素的地址).因此,下面两句等价:

int *arrPtr1 = &mArray[0];
int *arrPtr2 = mArray;

指针式遍历数组:intPtr++;

void travesalArray(){
	const unsigned short SIZE = 5;
	
	int intArr[SIZE] = {1,2,3,4,5};
	char charArr[SIZE] = {'F','i','s','C','o'};
	
	int *intPtr = intArr;
	char *charPtr = charArr;
	
	cout<<"intager array output: "<<endl;
	for(int i=0; i<SIZE; i++){
		cout<<*intPtr<<" at "<<reinterpret_cast<unsigned long>(intPtr)<<endl;
		intPtr++;
	}
	
	cout<<"character array output: "<<endl;
	for(int i = 0; i<SIZE; i++){
		cout<<*charPtr<<" at "<<reinterpret_cast<unsigned long>(charPtr)<<endl;
		charPtr++;
	}
}

输出结果如下:

intager array output: 
1 at 140729290089744
2 at 140729290089748
3 at 140729290089752
4 at 140729290089756
5 at 140729290089760
character array output: 
F at 140729290089776
i at 140729290089777
s at 140729290089778
C at 140729290089779
o at 140729290089780

四,结构体

(1) 结构体创建和使用

void tryStruct() {
	struct Student {
		string name;
		int age;
		char gender;
	};
	
    //第一种方式,赋值one by one
	Student stu1;
	stu1.name = "Sessy";
	stu1.age = 19;
	stu1.gender = 'F';
	cout<<"student1 info: "<<endl;
	cout<<"+name: "<<stu1.name<<endl;
	cout<<"+age: "<<stu1.age<<endl;
	cout<<"+gender: "<<stu1.gender<<endl;
	
	cout<<"-----------------------"<<endl;
	
    //第二种方式,like 数组
	Student stu2 = {"John", 18, 'M'};
	cout<<"student2 info: "<<endl;
	cout<<"+name: "<<stu1.name<<endl;
	cout<<"+age: "<<stu1.age<<endl;
	cout<<"+gender: "<<stu1.gender<<endl;
}

上图可以看到用"结构体变量.结构体成员"的方式来访问结构体成员;

(2) 用指针访问结构体成员

	Student *pStu = &stu2;
	cout<<"get struct info with pointer: "<<endl;
	cout<<"+name:"<<pStu->name<<endl;
	cout<<"+age:"<<pStu->age<<endl;
	cout<<"+gender:"<<pStu->gender<<endl;

五,传值,传址,传引用

(1) 传值

默认情况下,参数只能以值传递的方式给函数,也就是说被传递到函数的只是变量的值,不是变量本身.

int main() {
	int aa = 11, bb = 22;
	trySwapByValue(aa, bb);
	cout<<"aa == "<<aa<<", bb == "<<bb<<endl;
	return 0;
}

void trySwapByValue(int a, int b) {
	int temp = a;
	b = a;
	a = temp;
}

aa, bb将自己的值传给函数的参数a, b之后就和aa, bb没关系了.所以trySwapByValue里面再热闹,也跟aa, bb无关. 

(2) 传地址

int main() {
	int aa = 11, bb = 22;
	trySwapByAddress(&aa, &bb);
	cout<<"aa == "<<aa<<", bb == "<<bb<<endl;
	return 0;
}

void trySwapByAddress(int *a, int *b) {
	int temp = *b; //将b的地址暂存到temp
	*b = *a;       //指针b指向a的地址
	*a = temp;     //指针a指向b的地址
}

输出结果:aa == 22, bb == 11
成功交换了aa和bb 

(3) 传引用

int main() {
	int aa = 11, bb = 22;
	trySwapByReference(aa, bb);
	cout<<"aa == "<<aa<<", bb == "<<bb<<endl;
	return 0;
}

//为何称为传引用呢?--可能因为变量名被称为引用?
void trySwapByReference(int &a, int &b) {
	int temp = b;
	b = a;
	a = temp;
}

输出结果:aa == 22, bb == 11
成功交换了aa和bb

六,对象

小demo一个:

#include <iostream>
using namespace std;

#define FULL_GAS 81
class Car {
	public:
		string color;
		string engine;
		unsigned int gas_tank;
		unsigned int wheel;
	
	Car(void);
	void setColor(string color);
	void setEngine(string engine);
	void setWheel(unsigned int w);
	void fillTank(int liter);
	int running(void);
	void warning(void);
};

//constructor
Car::Car(void) {
	color = "Red";
	engine = "V8";
	wheel = 4;
	gas_tank = FULL_GAS;
}

void Car::setColor(string col) {
	color = col;
}

void Car::setEngine(string eng) {
	engine = eng;
}

void Car::setWheel(unsigned int w) {
	wheel = w;
}

void Car::fillTank(int liter) {
	gas_tank += liter;
}

int Car::running(void) {
	cout<<"I'm running at a high speed"<<endl;
	gas_tank--;
	cout<<"gas left: "<<100*gas_tank/FULL_GAS<<"%"<<endl;
	return gas_tank;
}

void Car::warning(void) {
	cout<<"WARNING!"<<endl;
	cout<<100*gas_tank/FULL_GAS<<"% oil in tank"<<endl;
}

int main() {
	char i;
	Car mCar;
	mCar.setColor("Yellow");
	mCar.setEngine("V8");
	mCar.setWheel(4);
	mCar.gas_tank = FULL_GAS;
	
	while(mCar.running()) {
		if(mCar.running() < 10) {
			mCar.warning();
			cout<<"Need to add oil?(Y/N)"<<endl;
			cin>>i;
			if('Y' == i || 'y' == i){
				mCar.fillTank(FULL_GAS);
			}
		}
	}
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值