c++中bool类型、三目运算符、const

c++新增加的类型——bool

sizeof(bool) ==1;

bool 数据类型只能取值 true(1),false(0)

bool bl = 54; printf("%d\n",bl);  //打印1

 

c++对三目运算符进行了功能增强:

int a = 20;
int b = 30;

(a < b ? a : b) = 90;  //在c编译器中不能通过
*( a < b ? &a : &b )=30 //c编译器通过

c编译器中,因为表达式的值是存放在寄存器中的,变量才是在内存中分配的,所以表达式不能作为赋值语句的左值(存在内存地址),但是对于三目运算符,在c++编译中是可以作为左值的,因为c++编译器对三目表达式做了增强,计算结果返回的是变量本身(c++的处理),而不是变量的值(c的处理)。对于上式,返回的是a,所以最后a=90成立。所以在c++编译器中,三目运算符中不能是常数:

(a < b ? 100 : b) = 90;  //在c++编译器中不能通过

 

c++中const改进:

同c的地方:基本功能一样

const int a ==> int const a

const int* a vs int const *a
void getnem(char** myp)
{
     char* p = (char*)malloc(100);
     *myp = p; 
}

void main()
{
     char buf[20];
     getnem(&buf);
}

/*
这里的 char** myp = &buf,所以,*myp ==>buf,但是在原函数中,*myp = p,这就导致了问题,因为
在*myp = p时,就默认传递的实际参数是可以被修改的,但是我们后来传递进去的地址值是不可被修改的,所以导致了问题发生。
*/

增强的地方:

void main()
{
    const int a=10;
    int* p = &a;
    *p = 1;
    printf("%d\n",a);   //c编译器打印为1,间接修改了a的值
}

/*
c语言中,const是一个冒牌的,不是说不能修改。
*/
void main()
{
    const int a=10;
    int* p = &a;    /*不能编译通过*/
    *p = 1;
    printf("%d\n",a);   
}



void main()
{
    const int a=10;
    int* p = (int*)&a;
    *p = 1;
    printf("%d\n",a);   //c++编译器打印为10
}

void main()
{
    const int a=10;
    int* p = (int*)&a;
    *p = 1;
    printf("%d\n",a);   //c++编译器打印为10
    printf("%d\n",*p);  //c++编译器打印为1
}

/*
打印的值不同,说明*p和a是两个不同的空间,这样的好处在于:不能再修改a的值了。
*/

/*
c++编译器中引入符号表概念:
const int a = 10; 这里的a和它的值被放进了符号表:
a 10
如果对a取地址——&a(或者是extern操作时),那么编译器为a重新开辟一个内存,所以这里的&a不是符号表中的a的地址,所以才会导致*p和a的值不同的局面。
*/

那么对const变量取地址时,新开辟空间,那么新开辟的空间地址是可预知的吗?

void main()
{
     int a =10;
     const int b = 20;
     int c = 30;

    printf("%x\n %x\n %x\n",&a,&b,&c);    //打印为连续的地址值
}
/* 上述a,b,c的空间是连续的,说明c++不是遇到&b才开辟一个新空间,而是一开始,通过预览操作得知了要进行&b操作,从而为b分配了空间,所以是连续的。 */

符号表是在c++编译器“编译”程序阶段创建的,所以在编译程序时,符号表中的已经是常量性质了,所以在c++程序中有以下成立:

void main()
{
    const int a =10;
    const int b = 20;

    int arry[a+b] ={0};   //c++编译器通过
}

c++中const变量既然是真正意义上的常量,那么与宏有区别吗?

宏是在预编译期间处理的,直接字符串替换,不进行类型检查和作用域检测;const变量是在编译期间处理的,要进行类型检测和作用域检测。

 1 void fun1()
 2 {
 3     #define a 10
 4     const int b = 20;
 5     //#undef
 6 }
 7 
 8 void fun2()
 9 {
10     printf("a = %d\n", a);   //正确
11     printf("b = %d\n", b);   //错误
12 }
13 
14 int main(int argc, char *argv[])
15 {
16     fun1();
17     fun2();
18     return 0;
19 }

这里的a是用宏定义的方式,由于不检测作用域的限制,所以#define的宏,只要从定义开始,一直到程序结束,都是可访问的。但是这里的const int b要进行作用域的检测,它只是在fun1函数中定义,但是fun2函数自然识别不到它的存在。

怎么使得宏只在固定位置可访问——比如说这里只在fun1函数中使用。

——使用#undef来结束#define的宏。

1 void fun1()
2 {
3     #define a 10
4     const int b = 20;
5     #undef a  //只卸载指定的a宏
6 }

那么这里的宏——b只能在代码行3-5行之间可以使用。

 

posted @ 2016-10-17 13:41  e-data  阅读(461)  评论(0)    收藏  举报