朝花夕拾--C++再学习
一,寻址
- 通过变量名
- 通过内存地址
取地址运算符&,用来获得变量的地址.
[code]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://www.geek-share.com/detail/2644386865.html
三,指针
既然指针变量存放的是一个地址,而32位系统的地址都是4个字节,为什么不用一个整型变量来存储而要发明指针呢?
如何根据指针变量来获取指针所存地址对应的值?--Deference(解引用),即在指针变量前加*号.
如std::cout<<*aPtr<<endl;
因此1,变量a和a的指针aPtr,代表同一个值,即a == *aPtr;
因此2,*aPtr = -100,将会修改a的值.
(1) *的两种用途:
1. 用于创建指针
[code]int *mPtr = &myInt;
2. 对指针进行解引用
[code]*mPtr = 123456;
(2) 指针与数组
数组的名字就是一个指针,它指向数组的基地址(也就是第一个元素的地址).因此,下面两句等价:
[code]int *arrPtr1 = &mArray[0]; int *arrPtr2 = mArray;
指针式遍历数组:intPtr++;
[code]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) 结构体创建和使用
[code]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) 用指针访问结构体成员
[code] 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) 传值
默认情况下,参数只能以值传递的方式给函数,也就是说被传递到函数的只是变量的值,不是变量本身.
[code]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) 传地址
[code]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) 传引用
[code]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一个:
[code]#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; }
- C++学习笔记之函数如何返回字符串(char型)
- C++学习的好网站
- C++入门学习笔记(三)--类的操作符重载
- C、C++的学习───思维方式的转变(2)
- 《深入学习:GNU C++ for Linux 编程技术》 第23章:使用标准模板库(STL)
- POCO C++库学习和分析 -- Foundation库SharedLibrary模块分析
- C++学习第五天
- [C++ Primer Plus]学习笔记--浮点数的优缺点
- [Book] C++ 学习推荐书籍
- C++基础学习—C++入门 c++相对于c,引入了什么东西
- c++学习笔记——虚函数(virtual function)
- c++ 学习中遇到的问题: error C2065: 'ifstream' : undeclared identifier
- C++ STL学习笔记一----map
- c++学习之new int()和new int[]的区别
- C++学习笔记之类于对象
- C++ 学习4 泛型编程 面向对象
- 从C#重返C++学习过程总结
- C++的学习笔记
- c++模板类学习
- 学习 C++ 的50条建议