现在的位置: 首页 > 综合 > 正文

(三)处理基本数据类型

2012年09月29日 ⁄ 综合 ⁄ 共 4431字 ⁄ 字号 评论关闭

1、混合类型表达式转换:总原则:不失真
       因此,一般都是由窄类型向宽类型转换。

2、随机数:  产生0到10:  a=rand() % 11
                        产生1到10:  a= 1+ rand() % 10

3、sizeof(类型或变量)取得内存所占大小,返回size_t(相当于unsigned int),t表示type,意即:字节大小。

4、numeric_limits<类型>::max()   求某数据类型的最大值(min()则求最小值)
       在头文件:#include<limits>中
      注意:浮点数的最小值是“能表示的最小正数
      如:cout<<numeric_limits<float>::min()<<endl;    //结果是1.17549e-38
      
      numeric_limits<类型>::digits 表示2进制数字的位数。注意:本质上表示有效位数。
       因此,对整形来就,例如int 其值就是31,因为有一位表示了符号位,所以总共是32位。
                   对于浮点来说,表示的是尾数。例如float,其值就是24位,因为第一位表示的符号位,另外7位表示的阶码。(内存中先符号位、再阶码,

5、位运算~(取反)、&(与)、^(异或)、|(或)
      其中异或在图形中运行用,假定color1、color2为两种色,mask=color1^color2是掩码,掩码作用大,与任意一个颜色异或就是另一个颜色。
      即color1^mask就是color2,同样color2^mask就是color2,因此可当color1为背景色,color2为前景色,用color2在color1上画图形后,要想
      快速消除,只须在原位再和mask异或得背景色即可消除此色,避免闪烁。

6、格式化<iostream>
      setw(N)   固定N个字符位,右对齐
      hex           整数按十六进制输出(浮点无效)
      dec           ..........十进制.......(平时默认就是这个
      setprecision(N)    设置小数位有N位(精度)
      setfill('0')   前缀位按0进行填充,改*则用*进行填充
      scientific   科学计算法表示
      fixed        相对浮点,用固定法表示(不带指数)
      oct           整数按八进制输出
      ----------------------------------------------------------------------
      left                 左对齐,右侧用填充符填充,默认填充为空格(setfill('0')则用0填充)
      right                 默认对齐方式,右对齐,..............................
     showpoint          给浮点数值显示小数点和尾数的0
     noshowpoint     与上相反,默认显示方式
     showbase          八进制输出前导显示0,16进制则显示0x
     noshowbase     默认显示方式,与上相反不显示前缀
     showpos           正数前面显示+
     nowshowpos   正数前面不显示+,系统默认显示方式
     uppercase        16进制显示整数时,大写字母A到F。若有showbase则加上0X。注意科学scientific时用E而非e
     nouppercase     默认方式,与上相反,小写
     boolalpha          bool型时值为true、false
     noboolalpha     把bool显示为1和0

// modify showpoint flag
#include <iostream>
using namespace std;

int main () {
  double a, b, pi;
  a=30.0;
  b=10000.0;
  pi=3.1416;
  cout.precision (5);
  cout <<   showpoint << a << '\t' << b << '\t' << pi << endl;
  cout << noshowpoint << a << '\t' << b << '\t' << pi << endl;
  return 0;
}

The execution of this example displays something similar to:

          30.000  10000.  3.1416
          30      10000   3.1416

7、枚举类型、枚举成员、枚举变量。
      默认其数值从0开始,后面逐个加1。可以特殊指定其值,注意它是具有const特质的,只接受字面和const进行赋值,之后不可更改。
     enum  alpha={A,B,C,D,E,F} //A为0,B为1,逐个加1
     enum  alpha={A=2,B,C=B+3,D=C-4,E,F}  //2,3,6,2,3,4
     enum  alpha={A='?',B='#',C='@',D='!',E='*',F='^'}  //说明其值不一定非得是整数
     ---------------------------------------------------------------------------------------------------------
    利用具有const不可更改的特性,由此引出“匿名枚举”这个概念,即不指定枚举类型,这样其成员就不准再次定义,相当于成员就是const 定义了。
    enum {A=34,B=23,C=67}  //后面语句就不准再更改A,B,C值,相当定义成const类型了。因此我们再利用它来求值,嘿嘿
    cout<<A*3*B<<endl;
    =============================================
     枚举变量,它是一个怪物,它可自动化装成其它类型,但是如果其它类型想转变过来,则需“强制”转换。
      1、定义法,可以是: emun    weekday{A,B,C,D,E=10} F;
                             也可是:enum    weekday{A,B,C,D};
                                             weekday F;
       2 、转变,
              自动转为其它类型:  int   c=B+3;//c就是2+3即5
              其它类型转过来需“强制”:   int    c=B+3;
                                                                F=static_cast<weekday>(c+3);//强制转换,8
        注意:F只能在weekday的最大值与最小值范围内取值,不一定得是某个成员值。上面取值为0,1,2,3,10,故范围为0到10,如果F超过个这范围即出错。

8、真正的替身:typedef   替代一个类型,而不是用它去替换字符串。
      注意下面的例子,ok是long,即long int,因此替代的是long int,而不是字符串long。

#include <iostream>
using namespace std;
typedef long ok;
int main(int argc, char *argv[])
{
	ok int a=3;  //出错,应为ok a=3;
	cout<<a<<endl;
	return 0;
}

9、变量的生存期:从“出生”(定义),到“死亡”(变量消失)的“活着”的期间。
      变量的作用域:就是生存期中,能发挥作用的范围,生存期并不全发挥作用,因为总有死角扫不到。

#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
	int a=10;
	cout<<a<<endl;
	{
		int a=30,b=3;
		cout<<a<<endl;
	}
	cout<<a<<endl;
	cout<<b<<endl;//出错,b已经死亡 
	return 0;
}

可以看到,最内括号虽然a仍然活着,但作用域扫不到了,因此内括号内的a相当于是另一个a,但出了内括号后,最开始的a又发生作用了。但其内的b死亡了,也就无作用域之谈。此例可以看出  生成期>作用域,当然还有生成期=作用域。它们总是从当前定义(出生“开始”)起作用。

     注意,前面所学的变量都是自动变量即auto,因为是系统默认方式,所以通常省略。另一个就是全局变量,它比auto更强大,即使不初始化,它也会自动指定为0,auto则不会,不使用初始化就会使用原来的垃圾值(指定的内存单元是啥内容就用啥内容,垃圾值)。
      作用域解析符::     不在作用域内强制使用全局作用变量

#include <iostream>
using namespace std;
int c; //全局变量,即便不初始化,也自动初始化为0 
int main(int argc, char *argv[])
{
	int c=3;
	cout<<::c<<endl;          //强制使用全局变量,值为0 
	{
		int c=10;
		::c=4;             //强制使用全局变量 
		cout<<c<<endl;     //输出 10
		cout<<::c*3<<endl;//强制作用全局变量 ,输出12 
	}
	return 0;
}

10、静态变量:statc       寄存器变量:register
        一个变量出了块,就会死亡。但有时我们想逆天改命,让它出了块而不死亡,怎么办呢?用static就可以让它延长寿命。静态变量的生存期和程序一样长。其它初始值自动为0.
       register为寄存器变量,即,它将使用CPU的寄存器,它的速度显然大大超过读取内存的速度。限制寄存器数据,寄存器变量的数量最多就2到3个,一般用于频繁读取的变量,如100000次循环,如果超过限制,将自动转为自动变量。同时注意,寄存器限制长度,寄存器变量只能是char、int、指针等,且不能取其地址(取&操作),不允许把外部变量和静态变量定义成寄存器变量。   当然现在编译器都已经优化了,知道怎么自动处理,寄存器变量只是对于以前老式机,如何提高速度而出来的产物 。

11、volatile修饰符。指定变量可以外部过程异步更改。

          volatile long data=9L;//可由其它处理过程更改。
          当不是volatile(易更改,刷新)变量时,编译器会重复使用以前加载在寄存器的已有值(以避免直接从内存中检索,现在的高速缓冲都这样,以节约时间,提高速度),但如果,异步过程更改了其值(内存中与寄存器中的同一变量的值不相同),这时变量前加上了volatile则在寄存器取值时,就会检索内存中的值是否一致。
           因为现在的编译器都是智能的,能自动优化,在寄存器中使用,如果异步改变了内存的值,结果前一个过程还在用成寄存器中的值(老的值),就会产生不一致现象,用volatile就告诉CPU,使用寄存器时要小心,随时要检索其内存是否发生了变化,以便随时更新。

抱歉!评论已关闭.