const 常量 解释 引用 函数

#include "iostream"
using namespace std;
//在c语言里面可以修改 const 是一个冒牌货 a是一个只读的常量, 通过地址绕过去
//在c++ 里面不能被修改?
void main()
{
	//在c++ 里面通过const修饰的东西,会变成什么样子?
	const int a = 10;
	int *p = NULL;
	//当对a取地址的时候,有一个内存空间(&a a的内存空间)
	p = (int*)&a;//对a 取地址,对符号表中的value 重新分配内存 这里为10
	printf("%x  %x\n",p,&a);
//	printf("*p:%d\n", *p);  
	printf("修改之前a:%d\n",a);
	*p = 11;//这里的修改和符号表 没有任何关系
	printf("修改之后a:%d\n",a);
	//printf("*p:%d\n",*p);

	system("pause");
}
//解释:
 //c++ 编译器对const 常量的处理
//当碰见常量声明时,在符号表中放入常量 问题:那有如何解释取地址
//编译过程中若发现使用常量则直接以符号表中的值替换
//结论:
//1,c语言中的const 变量是只读变量,有自己的存储空间
//2,c++ 中的const常量
 //  可能分配存储空间,也可能不分配存储空间
// 当const 常量为全局,并且需要在其他文件中使用
//当使用& 操作符 取const常量的地址

//补充
//符号表示key valuse形式的。

void fun1()
{
#define a 10

}
void fun2()
{
	printf("a=%d\n",a);
}
void main11()
{
	fun1();
	fun2();
}
 
  


#include "iostream"
using namespace std;
class Test1
{
public:
	Test1(int a=0,int b=0)
	{
		this->a=a;
		this->b=b;
	}
	Test1& T_add(Test1 &t2)
	{
	  this->a=this->a+t2.a;
	  this->b=this->b+t2.b;
	  return *this;
	}
	//从成员函数转化为全局函数 只需加一个this 指针(指向本类的类指针)

public :
	int a;
	int b;
};
//从全局函数转化为类的成员函数时,需要减一个左操作数参数
Test1 T_add(Test1 &t1,Test1 &t2)
{
	Test1 t3;
	t3.a=t1.a+t2.a;
	t3.b=t1.b+t2.b;
	return t3;
}
void main()
{
	Test1 t1(1,2),t2(3,4);
	system("pause");
}


对于函数的返回值,看似简单,但并非如此,比如:

int func(int a);该函数会返回一个int型,如果进行一个调用int result=func(3);会发生什么情况?

首先,func将返回值复制到一个匿名临时变量中,在这里假设该临时变量为anony(其实是没有名字的,这里方便阐述);然后,再将anony的值复制到result,可以看出,这里是进行了两次复制的。而并非一次复制。

 

对于返回引用的函数:

int & func(int &a);假设该函数传入一个int的引用,然后再func中修改它,再返回其引用,如果调用int reslut=func(b);会发生如下情况:

返回的是b的引用,因此相当于直接将b的值复制给了result。这里就只有一次复制(少了临时变量的复制,当然也创建了一个临时变量,只是该临时变量是b的一个引用)。

需要特别注意的是,按很多人的理解,这里返回的是一个引用,因此result就是b的引用,其实并非如此,这里返回引用只是减少了一次临时变量值的复制。如果真的要让result能够引用b,可以这样做:int &result = func(b);

注:返回普通变量的引用看不出效率的差异,但是返回比较大的类或者结构体的时候效率差异比较明显。

 

那如果是这样申明函数int func(int a);注意,这里返回的不是引用。然后int &result=func(a);会发生什么情况呢?

如果是这样,编译器将报错:不能用一个临时变量来初始化一个非常量的引用变量。

要消除这种报错,可以这样写const int &result=func(a);这样虽然返回的不是引用,但是由于最后赋给的是一个引用变量,因此在返回过程中也只有一次复制过程。但是这样的result是不能修改其引用的内容的。

 

还有一种看似更为诡异但却十分合理的情况:

int &func (int &a);同样假设该函数传入一个int的引用,在func中修改它,然后返回其引用。然后这样调用func(b)=3;这样的后果是,传入的b的值变为3。原因是func返回了一个b的引用,然后再将该引用赋为3,因此b的值也变成了3。

如果要禁止这种情况的发送,可以这样声明函数:const int &func(int &a);这样返回的是一个const引用,它不允许使用该引用修改其指向的值。因此如果有func(b)=3这样的调用,将通不过编译。

http://blog.csdn.net/piratejk/article/details/6162554


#include "iostream"
using namespace std;
int myf1()
{
  int a;
  a=11;
  return a;
}
int & myf2()
{
  int a;
  a=11;
  return a;
}
void main()
{
	int b1=myf1();
	int b2=myf2();//返回了一个值,返回赋给b2
	int &b3=myf2();
	printf("%d\n",b1);
	printf("%d\n",b2);
	printf("%d\n",b3);//b3 是一个引用类型 c++编译器会帮助我们执行*p
	system("pause");
}

int &j()
{
  static int a;
  a=10;
  printf("a:%d\n",a);
  return a;
}
void main()
{
	int b1=j();
	int &b2=j();
	//int b1=myf1();
	//int b2=myf2();//返回了一个值,返回赋给b2
	//int &b3=myf2();
	//printf("%d\n",b1);
	//printf("%d\n",b2);
	//printf("%d\n",b3);//b3 是一个引用类型 c++编译器会帮助我们执行*p
	//system("pause");
}

引用当左值

int &mygg()
{
	
  static int a=11;//a初始化的时候为10,只初始化一次
  printf("a:%d\n",a);
  return a;
}
void main()
{
	mygg()=11;//引用当左值
	mygg();
	system("pause");
}

int& myA(int &a)
{
  a++;
  return a;
}
void main()
{
	int b=10;
	int b1=myA(b);
	int b2=myA(b);
	int &b3=myA(b);
	printf("%d,%d,%d",b1,b2,b3);//11 12 13
	system("pause");
}
#include "iostream"
using namespace std;


struct AdvTeacher
{
	char name[32];
	int age ;
};

//
void getTeacher01(AdvTeacher **p)
{
	AdvTeacher *tmp = (AdvTeacher *)malloc(sizeof(AdvTeacher));
	tmp->age = 30;
	*p = tmp;
}

//这个是 结构体变量指针的引用 指针的引用
//p2是 t2 的别名
//
void getTeacher02(AdvTeacher * &p2)
{
	p2 = (AdvTeacher *)malloc(sizeof(AdvTeacher));
	p2->age = 30;
}

//如果不加引用 那么 myT3会copy给t3 
void getTeacher03(AdvTeacher &t3)
{
	t3.age = 11;
}

void main()
{
	AdvTeacher *t1 = NULL;
	AdvTeacher *t2 = NULL;
	getTeacher01(&t1);
	getTeacher02(t2);

	{
		AdvTeacher  myT3;
		myT3.age = 10;
		getTeacher03(myT3);

	}

	system("pause");
}

常引用

#include "iostream"
using namespace std;
struct Adv2Teacher
{
	  char name[32];
	  int age;
};
//const Adv2Teacher * const t3;
void getTeacher03(const Adv2Teacher &t3)//常引用
{
	//t3.age=110; 智能读不能写
	printf("%d\n",t3.age);
}
//const引用的作用,让变量所指向的内存空间只读
void main()
{
	//给const 引用初始化 有两种方法
	//1,让变量初始化const 引用
	int b=11;
	const int &a=b;
	//a=11; error 不能通过a间接修改b
	b=12;

	//2  const 引用的第二种初始化方法 
	///当使用常量(字面量)对const引用进行初始化的时候,c++ 编译器会为常量值分配内存空间,并将引用名作为这段空间别名
	//使用常量对const 引用初始化 以后将生成一个只读变量
	const  int &c=10;//10 是字面量
	//两种方式都分配了内存空间
	system("pause");
}

#include "iostream"
using namespace std;
//inline 请求关键字 内联编译
//内联函数体,需要和实现写在一起
#define MYFUNC(a,b)((a)<(b)?(a):(b))
inline int myfunc(int a,int b)
{
	return a((++a)<(b)?(++a):(b)) 3 3 3 
  printf("a=%d\n",a);
  printf("b=%d\n",b);
  printf("c=%d\n",c);
  system("pause");
}
void myPrint(int x=3)
{
	printf("x:%d\n",x);
}
//如果函数参数带默认值,那么右边的参数都带默认值
void myPrint2(int z,int x=3,int y=4)
{
	printf("x:%d\n",x);
}
void main默认参数()
{
	myPrint(5);
	myPrint(3);
	 system("pause");
}
//函数占位参数
//占位符参数一般用于程序扩展和对c代码的兼容
int func(int a ,int b, int =0)
{
   return a+b;
}
void main()
{
	func(1,2);
	system("pause");
}


#include "iostream"
using namespace std;
void myprintf(int a,int b)
{
	printf("a:%d,b:%d",a,b);
}
void myprintf(int a,int b,int c)
{
	printf("a:%d,b:%d,c:%d",a,b,c);
}
int func(int a,int b)
{
  return a+b;
}
int func(const char * s)
{
	return strlen(s);
}
int func(int x)
{
  return x;
}

//定义个数组类型
typedef int (Array)[10];
//定义一个(指向数组的类型)指针类型
typedef int(*pArray)[10];
//定义了一个指针 类型(指向函数的指针类型)
typedef int (*PFUNC)(int a);
void main()
{
	int c=0;
	//myprintf(1,2); //二义性
	Array my;//相当于 int my[10]
	pArray pmy=NULL;//相当于 Array* pMy;
	PFUNC p=func;
	c=p(1);
	printf("c=%d\n",c);
	system("pause");
}



你可能感兴趣的:(c++,精华)