C++
Week2
函数指针
程序运行期间,每个函数都会占用一段连续的内存空间。而函数名就是该函数所占内存区域的起始地址(也称“入口地址”)。我们可以将函数的入口地址赋给一个指针变量,使该指针变量指向该函数。然后通过指针变量就可以调用这个函数。这种指向函数的指针变量称为“函数指针”。
定义形式
类型名(* 指针变量名)(参数类型1,参数类型2,…);
#include <stdio.h>
void PrintMin(int a,int b) {
if( a<b )
printf("%d",a);
else
printf("%d",b);
}
int main() {
void (* pf)(int ,int);
int x = 4, y = 5;
pf = &PrintMin;
pf(x,y);
return 0; }
const void *a 定义了一个指针a,a可以指向任意类型的值。
命令行参数
将用户在CMD窗口输入可执行文件名的方式启动程序时,跟在可执行文件名后面的那些字符串,称为“命令行参数”。命令行参数可以有多个,以空格分隔。
int main(int argc, char * argv[])
{
……
}
argc: 代表启动程序时,命令行参数的个数。C/C++语言规定,可执行程序程序本身的文件名,也算一个命令行参数,因此,argc的值至少是1。 argv: 指针数组,其中的每个元素都是一个char* 类型的指针,该指针指向一个字符串,这个字符串里就存放着命令行参数。例如,argv[0]指向的字符串就是第一个命令行参数,即可执行程序的文件名,argv[1]指向第二个命令行参数,argv[2]指向第三个命令行参数……。
位运算
在计算机系统中,数值一律用补码表示和存储。含符号位和数值位,符号位:0表示“正”; 1表示“负”。
正数的补码 = 原码 负数的补码 = 负数的原码取反(符号位保持不变)+ 1
eg: [ -7 ]补=11111001(八位二进制) : 原码: 10000111—— 反码(符号位不变):11111000——加1得补码:11111001
对于有符号数,如long,int,short,char类型变量,在右移时,符号位(即最高位)将一起移动,并且大多数C/C++编译器规定,如果原符号位为1,则右移时高位就补充1,原符号位为0,则右移时高位就补充0。
#include <stdio.h>
int main()
{
int n1 = 15;
short n2 = -15;
unsigned short n3 = 0xffe0;
char c = 15;
n1 = n1>>2;
n2 >>= 3;
n3 >>= 4;
c >>= 3;
printf( "n1=%d,n2=%x,n3=%x,c=%x",n1,n2,n3,c);
} //输出结果是:n1=3,n2=fffffffe,n3=ffe,c=1
n1: 0000 0000 0000 0000 0000 0000 0000 1111
n1 >>= 2: 变成3
0000 0000 0000 0000 0000 0000 0000 0011
n2: 1111 1111 1111 0001
n2 >>= 3: 变成 fffffffe, 即-2
1111 1111 1111 1110
n3: 1111 1111 1110 0000
n3 >>= 4: 变成 ffe
0000 1111 1111 1110
c: 0000 1111
c >>= 3; 变成1
0000 0001
引用
类型名 & 引用名 = 某变量名;
- 定义引用时一定要将其初始化成引用某个变量。
- 初始化后,它就一直引用该变量,不会再引用别的变量了。
- 引用只能引用变量,不能引用常量和表达式。
引用作为函数的返回值
int n = 4;
int & SetValue() { return n; }
int main()
{
SetValue() = 40;
cout << n;
return 0;
} //输出: 40
常引用
定义引用时,前面加const关键字,即为“常引用”
int n;
const int & r = n;
r 的类型是 const int &
不能通过常引用去修改其引用的内容:
int n = 100;
const int & r = n;
r = 200; //编译错
n = 300; // 没问题
const关键字
- 不可通过常量指针修改其指向的内容
int n,m;
const int * p = & n;
* p = 5; //编译出错
n = 4; //ok
p = &m; //ok, 常量指针的指向可以变化
- 不能把常量指针赋值给非常量指针,反过来可以
const int * p1; int * p2;
p1 = p2; //ok
p2 = p1; //error
p2 = (int * ) p1; //ok,强制类型转换
- 函数参数为常量指针时,可避免函数内部不小心改变参数指针所指地方的内容
- 不能通过常引用修改其引用的变量
int n;
const int & r = n;
r = 5; //error
n = 4; //ok
动态内存分配
- 分配一个变量
T *P = new T
T是任意类型名,P是类型为T * 的指针。 动态分配出一片大小为 sizeof(T)字节的内存空间,并且将该内存空间的起始地址赋值给P。
- 分配一个数组
T *P = new T[N];
动态分配出一片大小为 N*sizeof(T)字节的内存空间,并且将该内存空间的起始地址赋值给P。
- delete p
- delete []p
内联函数,函数重载,函数缺省参数
- 内联函数
inline int Max(int a,int b) {
if( a > b) return a;
return b;
}
- 函数重载
一个或多个函数,名字相同,然而参数个数或参数类型不相同,这叫做函数的重载。
- 缺省参数
C++中,定义函数的时候可以让最右边的连续若干个参数有缺省值,那么调用函数的时候,若相应位置不写参数,参数就是缺省值。
void func( int x1, int x2 = 2, int x3 = 3) { }
func(10 ) ; //等效于 func(10,2,3)
func(10,8) ; //等效于 func(10,8,3)
func(10, , 8) ; //不行,只能最右边的连续若干个参数缺省
函数参数可缺省的目的在于提高程序的可扩充性。 即如果某个写好的函数要添加新的参数,而原先那些调用该函数的语句,未必需要使用新增的参数,那么为了避免对原先那些函数调用语句的修改,就可以使用缺省参数。
面向对象的程序设计
一类事物=>共同属性->数据结构,行为->函数=>类(先经过抽象,再经过封装)
类成员的可访问范围
关键字 – 类成员可被访问的范围
- private: 指定私有成员, 只能在成员函数内被访问
- public: 指定公有成员, 可以在任何地方被访问
- protected: 指定保护成员
类的成员函数内部, 可以访问:
- 当前对象的全部属性, 函数
- 同类其它对象的全部属性, 函数
类的成员函数以外的地方
- 只能够访问该类对象的公有成员