基础知识复习(难度3星)

C语言中函数的定义都是相互平行、相互独立的,也就是说在函数定义时,函数体内不能包含另一个函数的定义,即函数不能嵌套定义,但可以嵌套调用

---------------------------

循环----分为当型和直到型。当型就是常用的while,直到型是do while

----------------------------

C语言中变量以补码形式存放在内存中,正数的补码与原码相同,负数求补码方式为(符号位不变,其余各位取反,最后末尾加1);

      32位机器:int 32位,short 16位。

      x = 127,正数,原码:0111 1111,补码:0111 1111,扩展到32位高位补0,结果为0000007FH;

      Y = -9,负数,原码:1000 1001,补码:1111 0111,扩展到16位高位补1,结果为FFF7H;

      z = x + y = 118,原码:0111 0110,补码:0111 0110,扩展到32位高位补0,结果为00000076H。

      注意:扩展时,符号位不变。

----------------------------

int   *p[4];         //指针数组。  是个有4个元素的数组, 每个元素的是指向整型的指针 。(数组的每个元素都是指针) 
int   (*p)[4];       //数组指针。 它是一个指针,指向有4个整型元素的数组。                 (一个指针指向有4个整型元素的数组) 
int *func(void);     //指针函数。 无参函数, 返回整型指针。              (函数的返回值为int*) 
int (*func)(void);   //表示函数指针,可以指向无参, 且返回值为整型指针的函数。       (函数的返回值为int)

----------------------------

A:下面列举的几种情况不能省略模板实参:
1)从模板函数实参表获得的信息有矛盾之处。
2)需要获得特定类型的返回值,而不管参数的类型如何。
3)虚拟类型参数没有出现在模板函数的形参表中。
4)函数模板含有常规形参。
B:类模板与模板类的概念

⑴ 什么是类模板 一个类模板(也称为类属类或类生成类)允许用户为类定义一种模式,使得类中的某些数据成员、默写成员函数的参数、某些成员函数的返回值,能够取任意类型(包括系统预定义的和用户自定义的)。

  如果一个类中数据成员的数据类型不能确定,或者是某个成员函数的参数或返回值的类型不能确定,就必须将此类声明为模板,它的存在不是代表一个具体的、实际的类,而是代表着一类类。

⑵ 模板类是类模板实例化后的一个产物。可以从类模板派生出新的类,既可以派生类模板,也可以派生非模板类。

类模板的重点是模板。表示的是一个模板,专门用于产生类的模子。 模板类的重点是类。表示的是由一个模板生成而来的类。 

C:类模板有三种类型模板参数:类型模板参数、无类型模板参数和模板模板参数(以模板作为模板的参数)。并不局限于虚拟类型,非虚拟类型也可以作为类模板参数。

----------------------------

转换构造函数(conversion constructor function) 的作用是将一个其他类型的数据转换成一个类的对象。这里回顾一下以前学习过的几种构造函数:
1) 默认构造函数。以Complex类为例,函数原型的形式为:
    Complex( );  //没有参数

2) 用于初始化的构造函数。函数原型的形式为:
    Complex(double r, double i);  //形参表列中一般有两个以上参数

3) 用于复制对象的复制构造函数。函数原型的形式为:
    Complex (Complex &c);  //形参是本类对象的引用

现在介绍一种新的构造函数——转换构造函数。

转换构造函数只有一个形参,如
    Complex(double r) {real=r;imag=0;}
其作用是将double型的参数r转换成Complex类的对象,将r作为复数的实部,虚部为0。用户可以根据需要定义转换构造函数,在函数体中告诉编译系统怎样去进行转换。

在类体中,可以有转换构造函数,也可以没有转换构造函数,视需要而定。以上几种构造函数可以同时出现在同一个类中,它们是构造函数的重载。编译系统会根据建立对象时给出的实参的个数与类型选择形参与之匹配的构造函数。

假如在Complex类中定义了上面的构造函数,在Complex类的作用域中有以下声明语句:
    Complex cl(3.5) ;  //建立对象cl,由于只有一个参数,调用转换构造函数
建立Comptex类对象cl,其real(实部)的值为3.5,imag(虚部)的值为0。它的作用就是将double型常数转换成一个名为cl的Complex类对象。也可以用声明语句建立一 个无名的Complex类对象。如
    Complex(3.6) ;   //用声明语句建立一个无名的对象,合法,但无法使用它

可以在一个表达式中使用无名对象,如:
    cl =Complex(3.6);    //假设cl巳被定义为Complex类对象
建立一个无名的Complex类对象,其值为(3.6+0i),然后将此无名对象的值賦给cl,cl 在赋值后的值是(3.6+0i)。

如果已对运算符“+”进行了重载,使之能进行两个Complex类对象的相加,若在程序中有以下表达式:
    c = cl +2.5;
编译出错,因为不能用运算符“+”将一个Comptex类对象和一个浮点数相加。可以先将 2.5转换为Complex类无名对象,然后相加:
    c = cl + Complex (2.5);    //合法

请对比Complex(2.5)和int(2.5)。二者形式类似,int(2.5)是强制类型转换,将2.5转换为整数,int()是强制类型转换运算符。可以认为Complex(2.5)的作用也是强制类型 转换,将2.5转换为Complex类对象。

转换构造函数也是一种构造函数,它遵循构造函数的一般规则。通常把有一个参数的构造函数用作类型转换,所以,称为转换构造函数。其实,有一个参数的构造函数也可以不用作类型转换,如
    Complex (double r){ cout<<r; }  //这种用法毫无意义,没有人会这样用

转换构造函数的函数体是根据需要由用户确定的,务必使其有实际意义。例如也可 以这样定义转换构造函数:
    Complex(double r){ real =0; imag = r; }
即实部为0,虚部为r。这并不违反语法,但没有人会这样做。应该符合习惯,合乎情理。

注意:转换构造函数只能有一个参数。如果有多个参数,就不是转换构造函数。原因是显然的,如果有多个参数的话,究竟是把哪个参数转换成Complex类的对象呢?

归纳起来,使用转换构造函数将一个指定的数据转换为类对象的方法如下:
1) 先声明一个类。

2) 在这个类中定义一个只有一个参数的构造函数,参数的类型是需要转换的类型,在函数体中指定转换的方法。

3) 在该类的作用域内可以用以下形式进行类型转换:
    类名(指定类型的数据)
就可以将指定类型的数据转换为此类的对象。

不仅可以将一个标准类型数据转换成类对象,也可以将另一个类的对象转换成转换构造函数所在的类对象。如可以将一个学生类对象转换为教师类对象,可以在Teacher类中写出下面的转换构造函数:
    Teacher(Student& s){ num=s.num;strcpy(name, s.name);sex=s.sex; }
但应注意,对象s中的num,name,sex必须是公用成员,否则不能被类外引用

----------------------------

volatile:易变的,不稳定的。volatile用来声明那些可能在你的程序本身不知道的情况下会发生改变的变量。

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

对于一般变量:为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中。以后再取变量值时,就直接从寄存器中取值。

一个参数既可以是const也可以是volatile:一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。(简单点就是该程序代码不能试图去修改它,但不排除硬件方面修改了它,我们每次都得重新读取它的值。)

几个应用例子:

a. 并行设备的硬件寄存器(如:状态寄存器)。

b. 一个中断服务子程序中会访问到的非自动变量。(个人理解:中断服务子程序不能用缓存在寄存器中的值来判断事件,因为那个值可能被修改了,需要重新读取。所以一般需要把这种变量声明为volatile。)

c. 多线程应用中被几个任务共享的变量。

----------------------------

特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较:  

(1)16位平台  

char         1个字节8位 

short        2个字节16位 

int             2个字节16位 

long         4个字节32位 

指针         2个字节16位  

(2)32位平台  

char         1个字节8位 

short        2个字节16位 

int             4个字节32位 

long         4个字节32位

long long    8个字节64位  

指针         4个字节32位  

(3)64位平台  

char     1个字节 

short     2个字节

 int                 4个字节  

long             8个字节(区别) 

long long    8个字节  

指针             8个字节(区别)

----------------------------

静态成员问题

A.静态成员是所有对象共享,在实列化之前就存在,不属于对象。 B.当静态成员是const修饰的整型常量或者枚举型时可以在类内初始化,错误。 C.静态函数在类实例化之前就存在,故不存在this指针,错误。 D.静态函数只能访问静态成员,非静态函数能够访问静态,非静态成员。

----------------------------

运算符优先级顺口溜

学到的顺口溜,自己改了一下,方便记忆:

淡云一笔,鞍落三服(云淡风轻地大笔一挥,一个叫张三的人就从马鞍上落下来了)

淡:单目运算符

云:算数运算符

一:移位运算符

笔:比较运算符

鞍:按位运算符

落:逻辑运算符

三:三目运算符

服:赋值运算符

----------------------------

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值