• 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;
    }
    
  • 相关阅读:
    js实现选择切换
    Jquery操作select
    Mybatis 高级结果映射 ResultMap Association Collection
    jQuery的一些特性和用法
    利用JSONP解决AJAX跨域问题的原理与jQuery解决方案
    List转成Array 连个Array比较
    3.15
    Get 和 Post 方法的选择和URL的设计
    fd
    如何维护一个1000 IP的免费代理池
  • 原文地址:https://www.cnblogs.com/ygjzs/p/12074403.html
Copyright © 2020-2023  润新知