C++编程基础二 03-const形参与实参
1 // C++函数和类 03-const形参与实参.cpp: 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 #include <string> 7 #include <array> 8 #include <climits> 9 #include <math.h> 10 using namespace std; 11 12 int cube1(int i); 13 int cube2(const int i); 14 int pCube1(int *pi); 15 int pCube2(const int *pi); 16 int pCube3(int *const pi); 17 int rCube1(int &r); 18 int rCube2(const int &r); 19 int main() 20 { 21 22 //一般变量来说,其实没有顶层const和底层const的区别,而只有向指针这类复合类型的基本变量,才有这样的区别。 23 //如何区分顶层const和底层const? 24 //1.指向常量的指针(底层const):代表不能改变其指向内容的指针。声明时const可以放在类名前后都可以。 25 // 例如: 26 //int num_a = 1; 27 //int const *p_a = &num_a; //底层const 28 //*p_a=2; //错误,如果需要改变num_a的值,不能通过*pa来改变,只能num_a来改变值。 29 //2.指针常量(顶层const):代表指针本身是常量,声明时必须初始化。之后它储存的地址就不能再改变。声明时const必须放在*符号后面,即:*const。 30 // 例如: 31 //int num_b = 2; 32 //int *const p_b = &num_b; //顶层const 33 //p_b = &num_a; //错误,常量指针不能改变储存的地址值。 34 //一个指针本身添加const限定符就是顶层const,而指针所指的对象添加const限定符就是底层const。 35 36 // 例子1:执行对象拷贝时有限制,常量的底层const不能赋值给非常量的底层const。 37 int num_c = 3; 38 const int *p_c = &num_c; //p_c为底层const的指针 39 //int *p_d = p_c; //错误,不能将底层const指针复制给非底层const指针。 40 const int *p_d = p_c; //正确,可以将底层const指针复制给底层const指针。 41 42 //例子2:使用命名强制类型转换函数const_cast时,需要能够分辨底层const和顶层const,因为const_cast只能改变运算对象的底层const。 43 int num_e = 4; 44 const int *p_e = &num_e; 45 // *p_e = 5; //错误,不能改变底层const指针指向的内容。 46 int *p_f = const_cast<int *>(p_e);//正确,const_cast可以改变运算对象的底层const。但是使用时,一定要知道num_e不是const的类型。 47 *p_f = 5; //正确,非顶层const指针可以改变指向的内容 48 cout << num_e; //输出5 49 50 //练习: 51 const int a = 1; 52 //int * pi = &a; //错误,&a是底层const是底层const,不能赋值给非底层const 53 const int *pi = &a; //正确,&a是底层const,可以赋值给底层const 54 const int *const*const ppi = π //即是底层const,也是顶层const 55 const int *const*const*pppi = &ppi; //底层const 56 57 58 //_______________________________参考__________________________________________________ 59 60 61 int num1 = 10; 62 const int num2 = 10; 63 num1 = 20; //为int类型的变量,可以修改它的值 64 //num2 = 20; //int类型的常量,不可以修改它的值 65 66 int *p1 = &num1; //普通指针,int类型的变量可以初始化。也可以通过*p1修改int类型值。 67 // int *p2 = &num2;//出错 int类型的常量不可以初始化, 不能修改常量的值。 68 69 //在这里const包含两层含义: 70 const int *p3 = &num1; //底层const,int类型的变量和常量都可以初始化,但是不能通过*p3,*p4,去修改num1,num2的值。 71 const int *p4 = &num2; // 72 73 int *const p5 = &num1; //顶层const,int类型的变量可以初始化。 74 // int *const p6 = &num2; //出错 int类型的常量不可以初始化。 75 76 //int类型的引用,可以通过r1区修改num1的值,所以只能用int类型去初始化,不能用const int类型 77 int &r1 = num1; 78 // int &r2 = num2; //出错 79 // const int 类型的引用,不能修r3,r4的值 80 // 可以使用int类型的数据来初始化,也可以使用const int类型 81 const int &r3 = num1; 82 const int &r4= num2; 83 84 //实参为int类型或const int 类型 85 cout << cube1(num1) << " "<<cube1(num2) << endl; 86 cout << cube2(num1) << " " << cube2(num2) << endl; 87 88 //实参只能为int类型 89 cout << pCube1(&num1) << endl; 90 // cout << pCube1(&num2) << endl; //出错 91 92 // 所以实参是int类型,也可以是const int类型 93 cout << pCube2(&num1) << " " << pCube2(&num2) << endl; 94 95 //所以实参类型只能是int类型。 96 cout << pCube3(&num1) << endl; 97 // cout << pCube3(&num2) << endl; //出错 98 99 // 实参只能是int类型 100 cout << rCube1(num1) << endl; 101 // cout << rCube1(num2) << endl; //出错 102 103 // 实参的类型可以是int类型,也可以是const int 类型 104 cout << rCube2(num1) << " " << rCube2(num2) << endl; 105 return 0; 106 107 } 108 109 110 //可以修改形参: 111 int cube1(int i) 112 { 113 //i = 0; //错误的: 114 return i * i*i; 115 } 116 //不可以修改形参i 117 int cube2(const int i) 118 { 119 //i=0; //出错 120 return i * i*i; 121 } 122 int pCube1(int *pi) 123 { 124 *pi = 0; 125 return *pi*(*pi)*(*pi); 126 } 127 128 //可以修改pi,但是不可以修改*pi.所以实参是int类型,也可以是const int类型 129 int pCube2(const int *pi) 130 { 131 //*pi = 0; //错误 132 return *pi*(*pi)*(*pi); 133 } 134 //不可以修改pi,但是可以修改*pi,所以实参类型只能是int类型。 135 int pCube3(int *const pi) 136 { 137 *pi = 0; 138 return *pi*(*pi)*(*pi); 139 } 140 //可以修改r,实参只能是int类型 141 int rCube1(int &r) 142 { 143 //r = r * r*r; 144 return r * r*r; 145 } 146 //不可以修改r,实参的类型可以是int类型,也可以是const int 类型 147 int rCube2(const int &r) 148 { 149 //r = r * r*r; //出错 150 return r * r*r; 151 } 152 153 //总结: 154 //1.int cube(int i); 实参可以为int类型,也可以为const int类型。在函数体中可以修改i的值, 155 //函数不会修改实参的值。 156 //2.int cube(const int i); 实参可以为int类型,也可以为const int类型。在函数体中不可以修改i的值, 157 //函数不会修改实参的值。 158 //3.int pCube(int *pi); 实参为int* 类型的指针,不能为const int*类型。可以通过修改*pi的值修改实参指向的对象的值, 159 //修改pi对实参没有影响。 160 //4.int pCube(const int *pi);实参可以为const int*类型,也可以为int*类型。不可以通过修改*pi的值修改实参指向的对象的值, 161 //修改pi对实参没有影响。 162 //5.int pCube(int *const pi);实参为int*类型,不能为const int*类型。可以通过修改*pi的值修改实参指向的对象的值,不可以给pi赋值。 163 //6.void prest(int &r);实参为int类型,不可以为const int 类型。可以通过修改r的值,从而修改实参的值。 164 //7.void print(const int &r);实参可以为int类型,也可以为const int类型,不可以修改r的值。