C++_基本语法笔记_存储区_引用


与C语言完全相同的就没必要记录了


sizeof

sizeof不是函数,是个操作

short num = 10;
cout<<"short占用内存空间为:"<<sizeof(num)<<endl;
// 2 因为short占2个字节,int 4个字节,long 4个字节,long long 8个字节

float 类型

因为编译器默认会将小数认为是double型

所以,可以在数字后面加上“f”标记这个数值是float类型。
在这里插入图片描述
默认情况,打印6位有效数字,“3.14” 是3位有效数字

字符串

与C语言有一点差异,两者都可以

	//C语言风格
	char str1[] = "hello world";	//别忘了中括号
	cout << str1 << endl;

	//C++风格
	string str2 = "hello siri";		//记得包含头文件string.h
	cout << str2 << endl;

数据输入

  • cin>>输入字符串遇到空格就结束
  • bool型输入“true” 返回 0,输入100 返回 1
cin >> inputint;		
cin >> inputchar;
cin >> inputstring;				//hello siri
cin >> inputbool;				//100

cout << inputint << endl;
cout << inputchar << endl;
cout << inputstring << endl;	//hello		输入遇到空格结束
cout << inputbool << endl;		//1			输入非0值 返回都是真

取模运算

  • 两数相除,分母不能取0
  • 两个小数不能进行取模运算

随机数种子

srand((unsigned int)time(NULL)),记得添加头文件 <ctime>

程序内存模型

代码区

存放所有代码和注释,操作系统管理

全局区

全局变量(不在任何函数中,包括main函数以外)和静态变量(static)及常量(string字符串常量 和 const变量),操作系统管理

栈区

编译器分配,管理生成和消亡,存放参数值和局部变量

堆区

程序员分配,管理生成和消亡,若程序员不释放,程序结束后由操作系统释放

程序运行前

编译后,生成exe文件,未执行前:

代码区

  • 存放CPU执行的机器指令
  • 代码区是共享的,只存一份代码
  • 代码区是只读的,防止意外修改

全局区

  • 存放全局变量和静态变量
  • 全局区包含常量区,字符串常量和其他常量(const)都存放在常量区

程序运行后

栈区

  • 由编译器自动分配,存放函数的参数局部变量
  • 不要在函数内return 局部变量的地址,因为局部变量存放在栈,但是函数执行完会释放栈区,所以即使*p所指的地址没变,里面的值已经被释放了
int * func()
{
	int a = 10;
	return &a;		//返回这个局部变量的地址
}

int main()
{
	int *p = func();
	cout<<*p<<endl;		//10		是编译器的保留
	cout<<*p<<endl;		//乱码		第二次编译器不再保留	
}

堆区

  • 在C++中使用 new关键字 在堆区开辟内存
int * func()
{
   int *p = new int (10);
   return p;		//返回这个局部变量的地址
}

int main()
{
   int *q = func();
   cout<<*q<<endl;		//10		是编译器的保留
   cout<<*q<<endl;		//10		指向p的栈已经在func结束删除了,但是这里q接下了位置,并且所指位置的值没有释放	
}

这里是用栈中的指针保存了堆区的地址编号,和上面一样,p指向的地址没有变,但是堆没有释放,所以里面的的值一直都在。

new关键字

可以在堆区中开辟内存,完全结束前,不会被自动删除,可以用delete手动删除。

new 返回数据类型的指针

string *func_new()
{
	string *p = new string("这里测试new符号");
	return p;
}

void test_new()
{
	string *q = func_new();
	cout << *q << endl;
}

int main() {

	test_new();

	system("pause");

/*
这里测试new符号
*/

释放new出来的数组空间,需要用
delete [] arr

int* func_new_array()
{
	int* arr = new int[10];
	for (int i = 0; i < 5; i++)
	{
		arr[i] = 10 - i;
	}
	
	return arr;
}

void test_new_array()
{
	int* q = func_new_array();
	for (int i = 0; i < 5; i++)
	{
		cout << q[i]<<endl;
	}

	//对数组释放
	delete[] q;
}

int main() {

	test_new_array();

	system("pause");

/*
10
9
8
7
6
*/

引用

基本语法

作用:给变量起别名(也指向原名的地址,共享地址)
语法:数据类型 &别名 = 原名

引用的本质还是指针,不过,是不变的指针常量

注意点

  • 引用必须初始化
    不能int &b;,必须int &b = a;,像这样声明 b 的时候就确定地址

  • 初始化后,就不可以改变。

int main() {

		//引用
	int a = 10;
	int& b = a;
	
	cout << "a = " << a << endl;			//a = 10
	cout << "b = " << b << endl;			//b = 10
	
	//新变量c存储20
	int c = 20;
	//更改引用,会出问题
	b = c;
	cout << "a = " << a << endl;		// a = 20  会连着a的值一起修改,这有问题
	cout <<" b = " << b << endl;		// b = 20
	system("pause");

这样操作引用的结果就是,本意不想改变a的值,实际上在更改引用的时候,连着改变了a

做函数参数

函数操作会影响输入参数的实际值,而不是浅拷贝那样使用参数作为输入。

//传递地址 交换值
void swap_by_address(int *a,int *b)
{
	int temp;		//int变量
	temp = *a;		//temp得到a地址的值
	*a = *b;		//交换a地址的值 和 b地址的值
	*b = temp;	
}


//传递引用 交换值
void swap_by_ref(int &a, int &b)
{
	int temp;		//传入引用(别名)
	temp = a;		//temp等于真实的a
	a = b;			交换真实的a和b
	b = temp;
}

int main() {

	int swap1 = 11;
	int swap2 = 22;

	cout << swap1 << endl;			//11
	cout << swap2 << endl;			//22

	//swap_by_address(&swap1,&swap2);		//地址传递
	swap_by_ref(swap1, swap2);				//引用传递

	cout << swap1 << endl;			//22
	cout << swap2 << endl;			//11
	system("pause");
}

通过引用参数产生的效果和按地址传递一样,引用更明确一点。

做函数的返回值

  • 不要返回局部变量的引用

引用的本质其实也就是指针(常量),back其实指的是a的位置,但是局部变量a在函数结束后就销毁了,因此别名back也不能正常使用。

int& reback()
{
	int a = 10;
	return a;
}

void main()
{
	int &back = reback();

	cout << back << endl;
	cout << back << endl;		//可能会乱码,和之前一样,局部变量存在栈区,函数结束就删除
	
	system("pause");
}
  • 函数调用可以作为左值

函数的返回值是引用的话,这个函数可以作左值。

int& reback()
{
	static int a = 10;		//记得这里用static防止被清除
	return a;
}

void main()
{
	int &back = reback();	//back作为reback返回值a的别名

	cout << back << endl;
	cout << back << endl;

	reback() = 1000;		//reback()=1000,等价于back=1000

	cout << back << endl;
	cout << back << endl;
		
	system("pause");
}

引用的本质

引用的本质在C++内部是一个指针常量,指针指向不可变化。

void main()
{
	int ref_val = 10;
	int& ref = ref_val;		//内部进行 int *const ref = ref_val  ,也就是声明一个指针常量ref
		
	ref = 20;				//内部进行 *ref = 20  ,将指针ref的值赋值为20
	cout <<"ref_val = " << ref_val << endl;
	cout <<"ref = " << ref << endl;
	
	system("pause");
}

常量引用

  • 用const可以直接对引用值赋值
int main()
{
	int const_ref_val = 111;
	//	int& const_ref = 100;		//引用必须引一块合法的内存空间
	const int& const_ref = 100;		//编译器自动完成: int temp = 100; const int &const_ref = temp;
}
  • 常用来修饰形参,防止误操作:形参误改实参
void showValue(int& val)	//形参应该改为const int &val  就可以用const修饰形参,防止误更改val引用的值
{
	val = 1000;
	cout << "val = " << val << endl;
}

int main()
{
	int show_ref_val = 10;
	showValue(show_ref_val);
	//这里的show_ref_val本来只是想输出,不小心在函数showValue中被修改了值,导致show_ref_val也被改为1000,这是有问题的
	cout << "show_ref_val = " << show_ref_val << endl;			//show_ref_val = 1000
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值