您的位置:首页 > 其它

const 常量 解释 引用 函数

2015-03-23 14:50 169 查看
#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();
}
</pre><pre name="code" class="cpp">


#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<b?a:b;
}
void main1()
{
int a=1;
int b=3;
//int c= myfunc(++a,b);;//2 3 2
int c=MYFUNC(++a,b);//==>((++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");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: