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行之间可以使用。
内在的趣味,表面的繁琐

浙公网安备 33010602011771号