C++基础知识第二天

1. 变量的本质

变量都是有内存空间的,当它在堆栈区时可以通过指针修改它的值。

2.引用

本质地址传递;编译器帮忙做了基本地址传递的部分。

int &b = a;=====> int * const b = &a;(实质) b常指针,指向不可以改变。

(本质上:引用是一个常指针)

1)同一个内存块可以取多个别名。
int& b = a;
int& c = a;

2)引用的基本语法:
int a = 10;
int &b = a;(引用)
b = 100;
cout << a << endl; cout << b << endl;

输出的结果都为 100.

3)指针的引用;
int *p = NULL;
int *&p1 = p;
p1 = (int *)malloc(sizeof(int));

4)数组的引用:(两种方式)

1.
typedef int ARR[10];/*建立数组类型*/
int a[10];/*创建一个数组*/;
ARR &p = a;/*对数组的引用*/
p[i] = i;/*对数组的某个元素赋值*/

2.
int (&p1)[10] = a;/*直接建立数组类型,进行引用,并初始化。*/
p1[i] = i; /*对数组的某个元素赋值*/

"注意内容:"

5) 引用没有定义,是一种关系型声明。声明它和原有某一变量(实体)的关系。故而类型与原类型保持一致,且不

分配内存。与被引用的变量有相同的地址

声明引用变量时必须初始化, int& b; //错误

必须确保引用是和一块合法的内存块关联( NULL 不可内存不可引用)。

可以建立数组引用。

6)引用一旦初始化,不能改变。(原因如上:本质)

int &b = a; b = c (这种写法并不是改变b的指向,是将c的值赋给 b; b并没有指向c);

7)(常量引用)const int &b = a; b的值、指向都不能改变。

因为它等同于: const int *const b = &a;(这种写法常用来保护"实参"不受"形参"的改变).

8)C++编译器在编译过程中使用"常指针"作为引用的内部实现,因此引用所占用的空间大小与指针相同。(非官方的说法,但是大家都这么说)

9)

//建立普通变量的引用

int ma = 9;

int &ra = ma; //建立引用。 ===》 int *const ra = &ma; 即 ra = &ma;

ra = 88; //通过引用修改变量的值。这步是编译器帮忙进行解引用,然后赋值的。

//建立对指针的引用

int *p2 = NULL;

int *&mp2 = p2; //建立引用。===》 int ** const mp2 = &p2;

mp2 = (int *)malloc(sizeof(int)); //通过引用给指针p2分配空间。也就是给p2重新赋值,让他重新指向。

//建立对数组的引用

typedef int Arr[10]; /*建立数组类型 */ Arr a; //建立一个普通数组

Arr &p3 = a; //建立引用 ===》 Arr * const p3 = &a;

p3[3] = 10; //对数组的第四个元素赋值。

3.引用的几点基本知识:

1)单独定义引用时,必须初始化;说明它很像一个常量,因为常亮在定义时也必须初始化(const int a = 5)。

2) 普通引用有自己的空间。(在32位平台下占4个字节。)但是引用变量的地址和初始化它的变量是同一块地址。

int &a = b; a 和 b 的地址相同。()

struct teacher {int a; char b; int &d; double &c; }; 这个结构体所占内存为16;

struct teacher {int a; char b; }; 这个结构体所占内存为8;

3)引用的本质是一个常量指针。

3.函数中的引用:引用做函数的参数,引用做函数的返回值

1)引用做参数不需要初始化

2)不能返回局部变量引用;(和返回局部指针变量原因一样)。

3)引用做返回值。(可以做左值和右值)

4)指针的引用。

5)(常量引用):const 对引用的使用(如上:)。const 引用的值不能修改(主要用在函数的形参:不想用形参改变实参的值)

6)"函数的返回值当左值需要返回引用。"

4.类:

1)使用class关键字

2)类里面可以放变量、函数。

3)public: 访问权限

5.内联函数

C++中使用(既有宏函数的效率,又没有普通函数的开销;可以像普通函数那样,进行参数,返回值类型的安全检查,又可以

作为成员函数。 在C++中,定义内联函数,只是对编译器的一个建议,并不一定会成为内联函数。

(内联函数的语法)

1)普通函数; inline void func(int x){ return; }但是必须注意必须函数体和声明结合在一起,否则编译器将它作为普通函数来对待。

2)要求:不能存在任何形式的循环语句;不能存在过多的条件判断语句; 函数体不能过于庞大; 不能对函数进行取址操作

6.宏函数:C语言中使用

1) #define ADD(X, Y) X+Y

int main() {
int ret = ADD(10,20);
return 0;
}

2)副作用很多:无脑替换,不检查语法;没有作用域,从定义开始到文件结束

7.函数的默认参数和占位参数:

1)默认参数:int func(int x = 10,int y = 20);此时形参的赋值就是默认参数,当函数调用不传参数时,就将使用默认参数。。

2)注意:

int func051(int x, int y = 0, int z = 0);//函数的默认参数从左向右,如果一个参数设置了默认参数,那么这个参数之后的参数都必须设置默认参数。

函数的声明和函数的定义不能同时写默认参数,("即使默认参数相同也不行")编译器不知道该选择哪套

3)占位参数:

"函数的占位参数也是参数,必须要给个值,只是函数内部用不了而已. " int func(int , int y);或 int func(int ,int y = 3);

当占位参数与默认参数结合时:int func(int =5, int y);"erro" ;这种写法,int (int y, int =30);占位参数只能写在最后一个形参的位置。

而且可以不给它传参。因为它有了默认参数。

8.函数重载:

1)函数重载的条件:

"可以作为条件的:"

同一个作用域:函数名相同,形参的个数、形参的类型、形参的类型顺序不同;

用 const 进行修饰的函数也可以进行重载。 非 const 对象优先调用非 const 函数。

const 对象只能调用 const 函数,const 函数只能调用 const 函数,可以被 const 函数和非 const 函数调用。

注意:不可以作为条件的

"函数的返回值不能作为函数重载的条件"

"函数重载和默认参数不能同时出现";函数重载碰到默认参数,那么要考虑是否会出现函数调用二义性(会报错,编译通不过)。

2)重载函数的调用:

正常调用:"函数调用正常匹配函数形参(可以找到)。"

隐式类型转换后调用:"当找不到匹配的形参时,编译器会进行隐式转换,仍然找不到后会进行报错。(如下)"

void func(char b); int main(){ int a = 3; func(a);} 此时就会进行隐式转换,因为与ASCII码匹配。

3)函数重载的原理:

编译器为了实现函数重载,在编译的时候做了一些优化,用不同的类型来修饰不同的函数名。

如:void func(){}

void func(int a){}

void func(int a,char b){}

上述三个函数编译完后:生成的函数名为:_z4funcv "v代表void,无参数"

_z4funci "i代表参数为int类型"

_z4funcic "i代表第一个参数为int类型,第二个参数为char 类型"

本页共95段,3359个字符,7092 Byte(字节)