C++学习笔记1,面试常问(适合有基础)

1.函数可以声明多次,但只能定义一次

2.在32位操作系统下(x86),不管什么类型的指针,都是占用四个字节的内存空间,在64位操作系统下(x64),则占用8个字节

3.空指针:指向内存编号为零的空间,空指针指向的内存是不可访问的

4.const修饰指针

(1)const int* p=&a; 常量指针
特点:指针的指向可以改变,指针指向的值不可以改变
(2)int* const p=&a; 指针常量
特点:指针的指向不可以改变,但指针指向的值可以改变
(3)const int* const p=&a;
指针的指向和指针指向的值都不可以改变

5.sizeof数组与指针

int arr[5]={1,2,3,4,5}
int* p=arr;
cout<<sizeof(arr)<<endl;
cout<<sizeof(p)<<endl;
//结果为:
//20
//4(x64下为8)
//无论什么类型的指针都占4(x64为8)个字节

6.结构体

struct 结构体名{成员列表};
通过结构体创建变量的方式有四种:
struct 结构体名 变量名;
struct 结构体名 变量名={成员1,成员2…}
结构体名 变量名;
定义结构体时顺便创建变量

struct student{
	int age;
	int height;
}s4;
int main(){
	struct student s1;//第一种创建变量方式
	student s2;//第二种
	student s3={19,130};//第三种
}

7.C++内存分区模型

  • 代码区:存放函数体的二进制代码,代码区是共享的,只读的
  • 全局区:存放全局变量、静态变量、常量,该区域的数据在程序结束后由操作系统释放
    常量包括字符串常量和const修饰的全局变量,const修饰的局部变量
    字符串常量和const修饰的全局变量(全局常量)存放在全局区
    const修饰的局部变量(局部常量)存放在栈区
  • 栈区:存放函数参数值及局部变量,由编译器自动分配和释放内存
    注意:不要返回局部变量的地址和引用,因为该变量的内存空间已被回收
  • 堆区:动态申请的存储空间,由程序员控制它的分配和释放,若未释放,则程序运行结束后由系统进行回收
    //malloc和free
char* str=(char*)malloc(sizeof(char)*100);
free(str);
   new 数据类型    返回的该数据类型的指针
   通常在虚构函数中用delete释放
   释放数组要加[]

8.引用:给变量起别名

(1)用法:数据类型 &别名=原名

int a=10;
int &p=a;
p=20;

(2)引用必须初始化,引用初始化后就不可以改变

int &b;//错误的,因为没有初始化

(3)不要返回局部变量的引用,因为引用指向的内存空间已经不归该变量所有

int& func(){
	int temp=10;
	return temp;
}
int main(){
	int &ret=func();
	cout<<ret<<endl;//第一次正确,因为编译器会做一个保存,但此时ret所指向的内存空间其实已经被回收
	cout<<ret<<endl;//第二次错误
}

(4)如果函数的返回值是引用,那么函数的调用可以作为左值

int& func(int &a){
	return a;
}
int main(){
	int a=10;
	func(a)=20;
	cout<<a<<endl;//a的值变为20
}

(5)引用的本质就是一个C++指针常量

int a=10;
int &p=a;//底层被转换为int* constp=&a;
p=20;//底层被转换为*p=20;

(6)常量引用:通常用来修饰函数形参,使被引用实体的值不会在函数内改变

void func(const int&p){}

(7)对原引用变量,权限只能缩小,不能放大

const int a=10;
int &p=a;//错误,因为原变量是常量,只能读,不能修改,而这种写法对原变量是可修改的,权限不能放大

int b=10;
const int&p1=b;//正确,权限可以缩小

int &ret1=10;//错误
const int &ret2=20;//正确

(8)引用的使用场景

//(1)做形参
//避免值传递导致的调用拷贝构造函数,效率低下,且无法修改实参
//以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而
//是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤
//其是当参数或者返回值类型非常大时,效率就更低
void swap(int &a,int &b){
	int temp=a;
	a=b;
	b=temp;
}
int main(){
	int a=10,b=20;
	swap(a,b);
	//a变为20,b变为10
	cout<<a<<endl;
	cout<<b<<endl;
}

//(2)做返回值
//注意做返回值时不要返回局部变量的引用

9.默认参数

默认参数必须在最右边

void func(int a,int b=20,int c=30){}

如果函数声明有了默认参数,那么函数实现就不能有默认参数,反之亦然,目的是防止出现二义性

void func(int a=10,int b=10);
void func(int a=20,int b=20);
//错误,出现了二义性,a,b的默认值究竟是多少?

10.占位参数

返回值类型 函数名(数据类型){}
占位参数也可以有默认值
比如可以用于区分前置递增和后置递增

void func1(int){}
void func2(int=20){}
class MyInteger{
public:
	int num;
	 MyInteger& operator++(){//前置递增
		this->num=this->num+1;
		return *this;
	}
	MyInteger operator++(int){//因为后式递增不允许链式编程(a++)++这种,故不返回引用
		MyInteger temp=*this;
		this->num=this->num+1;
		return temp;
	}
}

11.函数重载注意事项

(1)引用作为重载条件

    void func(int& a){}
    void func(const int&a){}
    //上面这两个是可以重载的
    int a=10;
    const int b=10;
    func(a);//调用的是第一个函数
    func(b);//调用的是第二个函数
    func(10);//调用的是第二个函数

(2)函数重载碰到默认参数

    void func(int a,int b=10){}
    void func(int a){}
    func(10);//将会出错,二义性
    func(10,20);//不会出错
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值