[TCP-IP详解卷1:协议.pdf](…\Documents\Tencent Files\2240031723\FileRecv\TCP-IP详解卷1:协议.pdf)
1.总结const与指针的关系
2.总结const与引用的关系
3.总结this指针
任务:
1.多线程、多进程
银行家算法,生产者–消费者,读者-写者
多线程线程的同步
哲学家就餐,写一个死锁版本,如何将其改成不死锁版本
银行转账问题,写上两个类型
A客户转给B客户,如何完成转账
互斥量、信号量、共享内存,消息队列,
任选其一剖析其底层实现
2.给一个变量,找到其绝对的物理地址
虚拟地址映射
在Linux下剖析底层malloc的实现
网络:TCP/IP协议第一卷
服务器和客户端如何实现,多线程,多进程
线程池,进程池
#ifdef __cplusplus
#include<iostream>
using namespace std;
#else
#include<stdio.h>
#endif
int main()
{
const int a = 10;
int b = 0;
int *p = (int*)&a;
*p = 100;
b = a;//在编译阶段b被替换为10
#ifdef __cplusplus
cout<<"a = "<<a<<"b = "<<b<<"*p = "<<*p<<endl;
#else
printf("a = %d b = %d *p = %d \n",a,b,*p);
#endif
}
C和C++的编译方式对常量的认知不同
如何知道编译器是按照不同的方式编译?
C++有四个强转形式:
(1)去常性强转
int *s = const_cast<int*>(&a);
int main()
{
const int a = 10;
const int &b = a;
int& c = (int&)a;
c += 100;
return 0;
}
int fun()
{
int a = 10;
return a;
}
int& funref()
{
int a = 20;
return a;//a变量已经死亡
}//从失效空间里面获取数据是不安全的
int * const funref()
{
int a = 10;
return &a;
}
int y = *funref();
int * const z = funref();
int main()
{
int x = fun();//10
int y = funref();//20
int& z = funref();//随机值
cout << x << " " << y << " " << z <<endl;
return 0;
}
临时量:将亡值
不能从已失效空间获取值
void fun(int* p)//void fun(int*& p)
{
int a = 10;
p = &a;//变量的生存期受到函数的影响
}
int main()
{
int* s = NULL;
fun(s);//对p本身的修改能不能修改到s---不可以
}
如何把一个变量以引用的形式返回?
使变量的生存期不受函数的影响,函数的生存期不影响变量的生存期
int& fun()
{
static int a = 10;//.data
return a;
}
函数的死亡不影响全局变量和静态局部变量的死亡,以及以引入进入的变量
int* fun()
{
int ar[10] = {12,23,34,45,56,67,78,89,90,100};
return ar;
//如果数组的大小改为1000,则主函数可以成功打印出数组的十个值
}
int main()
{
int *p = fun();//此时p为失效指针
for(int i = 0;i < 10;++i)
{
printf("%p => %d\n",p,*p);
//为printf函数重新分配栈帧,覆盖数组的值,打印出来的结果为随机值
p += 1;
}
return 0;
}
底层解析时,解析为自身为常性的指针,在定义时要初始化
引用和指针的区别:
从语法,引用是变量的别名
从汇编(底层),引用相当于自身为常性的指针
引用相比指针来说,安全一点
int a = 10;
int &b;
int * const b;
b = &a;
void fun(int &a)
{
int *p = &a;
a = 100;
*p = 200;
}
int main()
{
int x = 10;
int &y = x;
fun(x);
fun(y);
return 0;
}
void fun(int * const a)
{
if(a == NULL)
{
return;
}
int *p = &a;
a = 100;
*p = 200;
}
int main()
{
int x = 10;
int * const y = &x;
fun(&x);
fun(y);
return 0;
}
class Rectangle
{
private:
int left,top,right,bottom;
public:
Rectangle(int e = 0,int t = 0,int r = 0,int b = 0):left(e),top(t),right(r),bottom(b){}
//作为缺省的构造函数和带参的构造函数
//实现默认构造函数和带参的构造函数
//实现Set函数
void SetLeft(int e)
{
left = e;
}
void SetTop(int t)
{
top = t;
}
void SetRight(int r)
{
right = r;
}
void SetBottom(int b)
{
bottom = b;
}
//实现Get函数
int GetLeft() const {return left;}
int GetTop() const {return top;}
int GetRight() const {return right;}
int GetBottom() const {return bottom;}
void Show()const
{
cout<<"left-top point is (" <<left << "," <<top << ":)" <<endl;
cout << "right-bottom point is (" <<right << "," << bottom << ")" <<endl;
}
};
int main()
{
Rectangle r1;
Rectangle r2(1,1,20,20);
const Rectangle & r = r2;
r.GetLeft();
return 0;
}
准则:
调动构造函数的目的:
(1)进行对象的构建
(2)初始化对象
构造函数和拷贝构造函数使用列表方案对其进行初始化,其他函数不可以,为什么?
列表,初始化列表只能存活于构造函数,拷贝构造函数中
实现双向函数
class Object
{
private:
int value;
public:
Object(int x = 0):value(X){}
~Object(){}
void SetValue(int x) { value = x};
int GetValue() {return value;}
//使用一个函数实现SetValue和GetValue()函数的功能
//int & Value(Object * const this)
int& value() {return value;}
//const int & Value(const Object * const this)
const int& Value()const {return value;}
//不能说是函数重载
//返回值与函数没有联系
};
void fun(const Object &obj)
{
const int &x = obj.Value();
}
int main()
{
Object obj(10);
obj.Value();
const Object obj(20);
objc.Value();
Object obj(10);
int x = 0;
x = obj.Value();
obj.Value() = 100;
Object obj(10);
int x = 0;
x = obj.value();
obj.value() = 100;
}
|