C++笔记(3)

1.C/C++编译器默认的类型转换:
   
//1.
unsigned int a=1;
int b=-1;//int b——>unsigned int b=一个很大的数
char c=a>b?'a':'b';
printf("%c\n",c);//打印出'b'
//2.
unsigned short a=1;//——>int a=1;
int b=-1;
char c=a>b?'a':'b';
printf("%c\n",c);//打印出'a'
2.const在C99中和C++是一样的;而在C89中和C++有以下的区别:
   const定义:const修饰一个变量,表示该变量从此以后,不能再作为赋值的左值。
   在C语言中的const:
       1)不一定非得初始化。
const int a=10;
const int a;
//以上两种编译皆可以通过
       2)const修饰的量为常变量,不能为常量。
       3)不能当作常量使用,如定义数组大小。
const int a=10;
int array[a]={0};//编译不通过
       4)常变量的编译方式和普通变量没有区别。
const int a=10;
int *p=(int *)&a;//*p访问a的值
*p=20;
printf("%d%d\n",a,*p);//20,20
//a和*p的值都是从内存里面取的
   在C++中的const:
       1)一定要初始化。
       2)const修饰的量叫常量。
       3)完全可以当作常量数字使用,比如定义数组长度。
       4)常量的编译方式为:在编译过程中,把常量的名字替换成常量的值。
const int a=10;
int *p=(int *)&a;
*p=20;
printf("%d%d\n",a,*p);//10,20
       注意:以上情况都是初始值为常量的情况
       5)如果初始值为变量,此时C++的常量就变成C的常变量了(即等于C中的const)
int b=10;
const int a=b;//此时相当于C中的const
3.const和一级指针的结合
   (1)const修饰的是离它最近的类型(const 和多个*结合使用时,查看const右边有几个* ,const 修饰的是const右边的内容。而const只有修饰*才会参与类型)
         
            
   (2)编译器所做的事:保证const的安全,代码上不能有直接间接修改常量值的可能
            直接:让常量作为左值
const int a=10;
a=20;//错误,因为常量作为左值
            间接:泄露了常量内存的地址或引用,千万不能泄露给一个普通的指针或普通的引用变量
const int a=10;
const int a=10;
int *p=&a;//左:int *  右:const int *//false
int *const p=&a;//错误,左边是int *,右边是const int *,即泄露给一个普通的指针
const int *p=&a;//正确,左边是const int *,右边是const int *,即泄露给一个const的指针
    (3)类型转换问题:
             const与一级指针结合时,类型转换具体如下
             const int *-->int *  c  错误的类型转换
const int a=10;
int *p=&a;//左:int *  右:const int *//false
             int *-->const int *  正确的类型转换
int a=10;//左:int  右:int
const int *p=&a;//左:const int *  右:int *//true
             const修饰一个指针时,表示所指向的那块内存不可改,如果将它赋值给一个普通的指针,相当于给const修饰的那块内存修改了值,这就违背了const的属性,所以错误;反之,一个普通指针的内存地址是可以修改的,将它赋值给一块固定的内存地址是正确的。
             const与二级指针结合时,类型转换具体如下
             const int **-->int **  错误的类型转换
int a=10;//int   int
const int *p=&a;//const int *     int *
int **q=&p;//int **      const int **//false
// == int *-->const int *&
            int **-->const int **  错误的类型转换
int a=10;//int   int
int *p=&a;//int *     int *
const int **q=&p;//const int **      int **//false//因为p是变量地址,不可以直接赋值
//  ==  const int *-->int *&
            以下的例子,我们可以把其看作为一级指针的结合:
int a=10;
int *const p=&a;//int *    int *
int **q=&p;//int **     int *const *p-->*     const *//false
int a=10;
int *p=&a;//int *     int *
int *const *p=&p;//int *const *     int **-->const *    *//true
4.添加这个头文件可以通过这个方法查看变量类型:
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
     int a = 10;
     const int b = 10;
     cout << typeid(a).name() << endl;
     cout << typeid(b).name() << endl;
     return 0;
}

5.valatile:
   对于重载来说,和const的情况是一样的;
void func(int *a){}
void func(const int *a){}
//两者类型不同可以重载
void func(int *a){}
void func(int *const a){}
//两者类型相同不能重载
void func(int *a){}
void func(volatile int *a){}
//两者类型不同可以重载
void func(int *a){}
void func(int *valatile a){}
//两者类型相同不能重载
     但是在多线程(必须满足三个条件:内存的可见性,原子性和一致性,以下只确保了了内存的可见性和一致性问题)中,它还有其他的含义:
   (1)保证多线程执行过程中,对线程共享变量不进行线程缓存,优点就是实时改变物理内存的值,缺点便是降低效率。
bool isThreadRunning=false;
void *threadProc(void *args)
{
    while(!isThreadRunnning){}
}
void main()
{   
    pthread_create(&tid,NULL,threadProc,(void *)args);
    isThreadRunning=true;
}
            如果在全局变量isThreadRunning前加上volatile的话,就会直接从物理内存中取得isThreadRunning的值,具有实时性。
   (2)编译器不能对valatile修饰的变量进行指令顺序的调整。
volatile bool isConfigOver=false;
//main thread
loadConfig();//加载配置
isConfigOver=true;
if(isConfigOver)
{
}
//child thread
while(!isConfigOver);//检查系统配置已经加载完成,开始做事情
            在单线程中,指令顺序的调整【发生之时:可能是代码优化时造成指令顺序的调整】不影响程序最终结果;而在多线程中,如上例,若将主线程中的isConfigOver=true;放在加载配置之前,就会影响子线程的判断,可能就在加载配置之前就进行操作,从而没有达到程序的要求。
   所以在多线程中,它解决了多线程缓存内存可见性问题和指令顺序调整的问题。
6.引用与取地址:
int a=10;
int &b=a;//引用
&b=a;//取地址
//左边有类型叫引用,没类型,就叫取地址
7.引用和指针:
int a=10;
int &b=a;//引用
int *p=&a;//指针
//a,b,*p表示同一块内存。
   指针和引用的区别:
  •    变量定义时,名字左边有&,就是定义了一个引用变量;
  •    引用必须初始化;
  •    引用定义时,引用了哪块内存,就永不再变,就不能再引用其他内存了;
  •    引用只能定义一级引用,不能出现二级引用,指针可以多级指针;
  •    使用引用变量,永远访问的是它所引用的内存(不能访问4字节的指针内存)。
   所以,引用是更安全的指针,从汇编语言上来看,指针和引用的意义是相同的(先将引用/指针的地址取出,在该地址上进行赋值操作)。

8.指针数组,数组指针和函数指针:
                         

  


             









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章