
一、布尔数据类型: 在c语言里面我们知道是没有布尔数据类型的,而在C++中添加了布尔数据类型(bool),它的取值是:true或者false(也就是1或者0),在内存大小上它占用一个字节大小: 1、bool类型只有true(非0)和false(0)两个值。 2、C++编译器会将非0值转换为true,0值转换为false。 #include <stdio.h> int main(int argc, char *argv[]) { bool b = false; int a = b; printf("sizeof(b) = %d\n", sizeof(b)); printf("b = %d, a = %d\n", b, a); b = 3; a = b; printf("b = %d, a = %d\n", b, a); b = -5; a = b; printf("b = %d, a = %d\n", b, a); a = 10; b = a; printf("a = %d, b = %d\n", a, b); a = 0; b = a; printf("a = %d, b = %d\n", a, b); return 0; } 演示结果: root@txp:/home/txp# ./a.outsizeof(b) = 1 b = 0, a = 0 b = 1, a = 1 b = 1, a = 1 a = 10, b = 1 a = 0, b = 0 2、C++中的三目运算符: 对三目运算符,想必大家都再熟悉不过了,不过在c++中的三目运算符的用法就比c语言更加高级了,来先看一个示例: int a = 1; int b = 2; ( a < b) ? a : b = 3; printf("a=%d,b=%d\n",a,b); 上面的三目运算符语句看起来怎么有点奇怪,它作为左值了,一般在c语言里面它应该是作为右值赋值给一个变量的,那这样写在c++中有没有错误,答案肯定是没有错的,我们还是来看一下这种写法在c语言中报了啥错误: root@txp:/home/txp# gcc test.ctest.c: In function ‘main’: test.c:7:21: error: lvalue required as left operand of assignment ( a < b) ? a : b = 3; 这里我们可以发现它不能做为左值来对它进行赋值,而我们在c++编译器里面来编译,很明显它是没有错误的,行的通,那我们再来修改一下: #include <stdio.h>int main(void) { int a = 1; int b = 2; ( a < b) ? a : 4 = 3; printf("a=%d,b=%d\n",a,b); } 编译结果(这个错误和在c语言里面一样,注意这里我是在C++编译器里面编译,只是把三目运算符里面修改了一下。): root@txp:/home/txp# g++ test1.cpptest1.cpp: In function ‘int main()’: test1.cpp:7:23: error: lvalue required as left operand of assignment ( a < b) ? a : 4 = 3; ^ 小结: 1、c语言里面的三目运算符返回的是变量值,它不能作为左值来使用。 2、c++中的三目运算符可以直接返回变量本身,既可以作为右值使用,也可以作为左值来使用。 3、c++中的三目运算符可能返回的值中如果有一个是常量值,则不能作为左值进行使用,这点要切记和理解。 二、C++中的引用: 1、引用的概念: --引用可以看作一个已定义变量的别名 --引用的语法:Type &name = var;这里举个简单的示例: int a =4;int& b =a; //b为a的别名 b = 5;//操作b就是操作a --注意普通引用在定义时必须用同类型的变量进行初始化。 下面是demo演示: #include <stdio.h>int main(int argc, char *argv[]) { int a = 4; int& b = a; b = 5; printf("a = %d\n", a); printf("b = %d\n", b); printf("&a = %p\n", &a); printf("&b = %p\n", &b); return 0; } 演示结果: root@txp:/home/txp# ./a.outa = 5 b = 5 &a = 0x7fff408ffdec &b = 0x7fff408ffdec 2、引用的意义: --引用作为变量名而存在,因此在一些场合可以代替指针。 --引用相对于指针来说具有更好的可读性和实用性。 下面举个经典的例子来对比一下: (1)引用方式: #include <stdio.h>void swap(int& a,int& b) { int t = a; a=b; b=t; } int main(void) { int a =5; int b =6; printf("a=%d,b=%d\n",a,b); swap(a,b); printf("a=%d,b=%d\n",a,b); return 0; } 演示结果: root@txp:/home/txp# ./a.outa=5,b=6 a=6,b=5 (2)指针方式: #include <stdio.h>void swap(int *a,int *b) { int t =*a; *a=*b; *b=t; } int main(void) { int a =5; int b =6; printf("a=%d,b=%d\n",a,b); swap(&a,&b); printf("a=%d,b=%d\n",a,b); return 0; } 演示结果: root@txp:/home/txp# ./a.outa=5,b=6 a=6,b=5 3、特殊的引用: --在c++中可以声明const引用。 --const Type& name =var; --const 引用让变量拥有只读属性。 --当使用常量对const引用进行初始化时,C++编译器会为常量分配空间,并将引用名作为这段空间的别名: int a = 4;const int& b =a; int *p=(int *)&b; b=5;//错误,只读变量 *p=5;//修改a的值 下面来看一个示例: #include <stdio.h>void Example() { printf("Example:\n"); int a = 4; const int& b = a; int* p = (int*)&b; //b = 5; *p = 5; printf("a = %d\n", a); printf("b = %d\n", b); } int main(int argc, char *argv[]) { Example(); printf("\n"); return 0; } 演示结果: root@txp:/home/txp# ./a.outExample: a = 5 b = 5 4、引用有自己的存储空间吗? 话不多说,看试验就知晓: #include <stdio.h>struct TRef { char& r; }; int main(int argc, char *argv[]) { char c = 'c'; char& rc = c; TRef ref = { c }; printf("sizeof(char&) = %d\n", sizeof(char&)); printf("sizeof(rc) = %d\n", sizeof(rc)); printf("sizeof(TRef) = %d\n", sizeof(TRef)); printf("sizeof(ref.r) = %d\n", sizeof(ref.r)); return 0; } 演示结果: root@txp:/home/txp# ./a.outsizeof(char&) = 1 sizeof(rc) = 1 sizeof(TRef) = 8 sizeof(ref.r) = 1 很明显有它的内存大小,下面就来看一下引用的本质。 5、引用的本质: (1)引用在c++中的内部实现是一个指针常量,比如说说: Type& name; void fun(int& a) { a=8; } 等价于: Type* const namevoid fun(int* const a) { *a=8; } (2)C++编译器在编译过程中用指针变量作为引用的内部实现,因此引用所占用的空间大小与指针相同(可以结合上面的那个例子仔细回忆和理解一下)。 (3)从使用的角度,引用只是一个别名,c++为了实用性而隐藏了引用的存储空间这一细节。 (4)c++中的引用大多数的情况下代替指针: --功能性:可以满足多数需要使用指针的场合。 --安全性:可以避免由于指针操作不当而带来的内存错误。 --操作性:简单易用,又不失功能强大。 #include <stdio.h>struct TRef { char* before; char& ref; char* after; }; int main(int argc, char* argv[]) { char a = 'a'; char& b = a; char c = 'c'; TRef r = {&a, b, &c}; printf("sizeof(r) = %d\n", sizeof(r)); printf("sizeof(r.before) = %d\n", sizeof(r.before)); printf("sizeof(r.after) = %d\n", sizeof(r.after)); printf("&r.before = %p\n", &r.before); printf("&r.after = %p\n", &r.after); return 0; } 演示结果: @txp:/home/txp# ./a.outsizeof(r) = 24 sizeof(r.before) = 8 sizeof(r.after) = 8 &r.before = 0x7ffdeacc7a00 &r.after = 0x7ffdeacc7a10 再来看一个函数返回引用示例: #include <stdio.h>int& func() { static int s = 0; printf("func: s = %d\n", s); return s; } int main(int argc, char* argv[]) { int& rs = func(); printf("\n"); printf("main: rs = %d\n", rs); printf("\n"); rs = 11; func(); printf("\n"); printf("main: rs = %d\n", rs); printf("\n"); return 0; } 演示结果: root@txp:/home/txp# ./a.outfunc: s = 0 main: rs = 0 func: s = 11 main: rs = 11 三、总结: 1、bool的总结: --bool类型是c++新添加的基础类型。 --bool类型的值只能是true和false。 --c++中的三目运算符可作为左值来使用。 2、引用: --引用作为变量名而存在旨在代替指针。 --const引用可以使得变量具有可读属性。 --引用在编译器内部使用指针常量实现。 --引用的最终本质为指针。 --引用可以尽可能的避免内存错误。 |
希望楼主多多分享,赠人玫瑰,手有余香,念念不忘,必有回响;.