c++-引用

c++中引用类型,引用是如何引用的呢?

  • 引用
    • 引用概念,给变量起个别名,本质是给内存空间取个别名
    • 引用是c++的语法概念、引用的意义(好用)
    • 引用本质:有地址、定义时必须初始化,c++编译器内部按照指针常量
    • 引用结论:间接赋值成立的三个条件的后两步和二为一
    • 引用使用原则:当用引用时,我们不去关心编译器引用是怎么做的;当分析奇怪的语法现象时,才去考虑c++编译器是怎么做的
    • 函数返回值是引用(若返回栈变量,不能成为其他引用的初始化)
    • 函数返回值当左值,必须返回一个引用
    • 指针的引用int getT(Teacher * &myp )
    • 常引用
      • 用变量初始化const引用,然变量形参拥有只读属性
      • 用字面量初始化const引用,额外的分配内存空间
  • 引用概念,给变量起个别名,本质是给内存空间取个别名
  • 引用是c++的语法概念、引用的意义(好用)
  • 引用本质:有地址、定义时必须初始化,c++编译器内部按照指针常量
  • 引用结论:间接赋值成立的三个条件的后两步和二为一
  • 引用使用原则:当用引用时,我们不去关心编译器引用是怎么做的;当分析奇怪的语法现象时,才去考虑c++编译器是怎么做的
  • 函数返回值是引用(若返回栈变量,不能成为其他引用的初始化)
  • 函数返回值当左值,必须返回一个引用
  • 指针的引用int getT(Teacher * &myp )
  • 常引用
    _ 用变量初始化const引用,然变量形参拥有只读属性
    _ 用字面量初始化const引用,额外的分配内存空间

这与c大有不同

1 引用没有定义, 是一种关系型声明。声明它和原有某一变量(实体)的关
系。故 而类型与原类型保持一致, 且不分配内存。与被引用的变量有相同的地
址。

2 声明的时候必须初始化, 一经声明, 不可变更。

3 可对引用, 再次引用。多次引用的结果, 是某一变量具有多个别名。

4 & 符号前有数据类型时, 是引用。其它皆为取地址

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;
/*

*/

void change_value(int *p) // int p = a;
{
	*p = 30;
}

void change_value2(int & r)//int &r = a
{
	r = 30; //a = 30
}


int main(void)
{
	int a = 20;
	int b = 30;


	int *p = &a;
	*p = 30;

	p = &b;
	*p = 20;//b

	int &re = a; //int & 使用引用数据类型, re就是a的别名

	re = 50;
	&re;
	&a;

	re = b; //让re成为b的引用?   a = b
	re = 50;
	cout << "a =" <<a << endl;
	cout << "b = " << b << endl;
	int & re2 = b; //引用一定要初始化,

	re2 = a;


	int &re3 = re;

	re3 = 100;
	cout << "a =" << a << endl;
	cout << "re =" << re << endl;
	cout << "re3 =" << re3 << endl;



	cout << "-------------" << endl;
	cout << "a =" << a << endl;
	change_value(&a);//改变了值
	cout << "a =" << a <<  endl;
	a = 100;
	cout << "-------------" << endl;
	cout << "a =" << a << endl;
	change_value2(a);//改变了值
	cout << "a =" << a << endl;

	return 0;
}

引用示例

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;

struct student
{
	int id;
	char name[64];
};

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

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

void printS(struct student s) //student s = s1; 结构体整个值拷贝的动作
{
	cout << s.id <<" "<< s.name << endl;
	s.id = 100;
}

void printS1(struct student *sp)
{
	cout << sp->id << " " << sp->name << endl;
	sp->id = 100;
}

//引用在一定条件下能够取代指针的工作,也能作为函数参数。
void printS2(struct student &s)//student &s = s1;
{
	cout << s.id << "  " << s.name << endl;
	s.id = 300;
}

int main(void)
{
	int a = 10;
	int b = 20;

	my_swap2(a, b);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;


	student s1 = { 10, "zhang3" };

	printS(s1);
	printS1(&s1);
	printS2(s1);

	cout << "si.id =" << s1.id << endl;

	return 0;
}

引用的本质

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;

struct typeA
{
	int &a;
};

struct typeB
{
	int *a;
};


struct student
{
	int id;
	char name[64];
};

void motify(int *const a)//int *const a = main::&a
{
	*a = 300;
}

void motify2(int &a) //当我们将引用作为函数参数传递的时候,编译器,会替我们将实参,取地址给引用
					//int &a = main::&a
{
	a = 300; //对一个引用操作 赋值的时候,编译器提我们隐藏*操作。
}

//如果我们在去研究引用的时候,你可以将引用当做一个常指针去研究
//当你在使用引用编程的时候,你就把引用理解为变量的别名就可以了。


int main(void)
{
	cout << "sizeof(struct typeA)" << sizeof(struct typeA) << endl;
	cout << "sizeof(struct typeB)" << sizeof(struct typeB) << endl;
	//引用所占用的大小 跟指针是相等的。
	int a = 10;
	int &re = a; //常量要初始化,引用也要初始化, 引用可能是一刚常量。

	int *const p = &a;
	//综上两点, 引用 可能是一个常指针。


	motify(&a);

	motify2(a);

	return 0;
}

引用作为函数的返回值

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;

char * getmem(int num)
{
	char *p = NULL;
	p = (char*)malloc(num);//分配空间

	return p;//ox11223344
}//0x1231321

int getmem2(char **pp, int num)
{
	char *p = NULL;
	p = (char*)malloc(num);

	*pp = p;

	return 0;
}//0


int getA1()
{
	int a = 10;

	return a;
}//a的值



void getA2(int *a)
{
	*a = 10;
}

//引用作为返回值,不要返回局部变量的引用。
int& getA3()
{
	int a = 10;
	return a;
}//int &temp = a;

int &getA4()
{
	static int a = 10;

	return a;
}

int main(void)
{
	int a = 0;
	char *pp = NULL;

	a = getA1();
	pp = getmem(10);

	cout << "-----------" << endl;

	int main_a = 0;

	main_a = getA3(); //main_a = temp; //数值拷贝

	cout << "main_a " << main_a << endl;

	cout << "-----------" << endl;

#if 0	
	int &main_a_re = getA3(); 

	cout << "main_a_re " << main_a_re << endl;
	cout << "main_a_re " << main_a_re << endl;
#endif

	int &main_a_re = getA4();
	cout << "main_a_re " << main_a_re << endl;
	cout << "main_a_re " << main_a_re << endl;


	//引用如果当函数返回值的话,函数可以当左值。
	getA4() = 1000;



	return 0;
}

指针引用


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;

struct teacher
{
	int id;
	char name[64];
};


int get_mem(struct teacher** tpp)
{
	struct teacher *tp = NULL;
	tp = (struct teacher*) malloc(sizeof(struct teacher));
	if (tp == NULL) {
		return -1;
	}

	tp->id = 100;
	strcpy(tp->name, "li4");

	*tpp = tp;

	return 0;
}

void free_teacher(struct teacher **tpp)
{
	if (tpp == NULL) {
		return;
	}

	struct teacher *tp = *tpp;

	if (tp != NULL) {
		free(tp);
		*tpp = NULL;
	}
}


int get_mem2(struct teacher* &tp)
{
	tp = (struct teacher*)malloc(sizeof(struct teacher));
	if (tp == NULL) {
		return -1;
	}
	tp->id = 300;
	strcpy(tp->name, "wang5");

	return 0;
}

void free_mem2(struct teacher * &tp)
{
	if (tp != NULL) {
		free(tp);
		tp = NULL;
	}
}


int main(void)
{
	struct teacher *tp = NULL;

	get_mem(&tp);
	cout << "id =" << tp->id << ", name = " << tp->name << endl;
	free_teacher(&tp);

	cout << "00000000000" << endl;

	get_mem2(tp);
	cout << "id =" << tp->id << ", name = " << tp->name << endl;
	free_mem2(tp);

	return 0;
}
原文地址:https://www.cnblogs.com/ygjzs/p/12074403.html