1.3c++和C
C++是C的扩展 是C的超集
C++支持面向对象
C++支持泛型编程 模板(函数模板、类模板)---把类型作为一种参数传递
C++支持异常机制
C++支持运算符重载(实际上是函数重载的机制)
C++的类型检查更加严格
C++的类型更丰富 bool 引用
1.4第一个C++程序
songxl@ubuntu:~/cpp/day01$ cat hello.cpp
#include <iostream>
//头文件不同
//仍然可以使用C的头文件:stdio.h(cstdio)
int main(void)
{
std::cout<<"hello C++!" << std::endl;
//std是命名空间,是标准库的命名空间
//::域限定符
//cout输出对象
//<<插入运算符,返回的是cout对象,对基本的数据类型进行了运算符重载
//所以可以连起来用
return 0;
}
C++程序:
1)扩展名.cpp .C .cxx .cc;推荐使用.cpp
2)使用g++编译器
1.5命名空间实际上也叫名字空间
作用:
-----对代码进行逻辑分组,防止命名冲突
定义:怎样定义命名空间? namespace 命名空间名字
1 #include <iostream>
2 using namespace std;
3 namespace zhangsan{
4 void print(){
5 cout << "hello,zhangsan" << endl;
6 }
7 }
8 namespace lisi{
9 void print(){
10 cout << "hello,lisi" << endl;
11 }
12 }
13 namespace lisi{
14 /* void print(){
15 cout << "cout 2" << endl;
16 }
17 */ void add(int a,int b)
18 {
19 cout << a+b << endl;;
20 }
21 int sub(int a,int b);
22 /*{
23 cout << a-b << endl;
24 }*/
25 }
26 int lisi::sub(int a,int b)
27 {
28 //cout << a-b << endl;
29 return a-b;
30 }
31 void print()
32 {
33 cout <<"全局的print()" << endl;
34 }
35 int main()
36 {
37 zhangsan::print();
38 lisi::print();
39 lisi::add(3,5);
40 cout << lisi::sub(5,3)<< endl;;
41 using namespace zhangsan;
42 // print();
43 using namespace lisi;
44 // print();//出现歧义
45 lisi::print();
46 ::print();
47 add(4,5);
48 return 0;
49 }
命名空间的指令:
using namespace 命名空间的名字
命名空间是可以分开定义的
在命名空间中函数的定义和声明分开怎么写?
对于全局的函数来说,其命名空间在调用时用::即可。
命名空间声明:
using namespace 命名空间的名字::要声明的名字
;意思是只让部分暴漏出来。
1.6 C++中的结构、联合与枚举
1)结构
A: 在声明结构类型的变量时不用再使用struct关键字了
B: 在结构中可以声明函数
1 #include <iostream>
2 using namespace std;
3
4 int main()
5 {
6 struct Student{
7 char name[32];
8 int age;
9 void show(void){
10 cout << "name:" << name << " age:" << age << endl;
11 }
12 };
13 struct Student stu={"john",22};//c define method
14 Student stu2={"tom",23};
15 stu.show();
16 stu2.show();
17 return 0;
18 }
2)联合
A: 在声明联合类型的变量时不用再使用union关键字
B:支持匿名联合
1 #include <iostream>
2 #include <cstdio>
3 using namespace std;
4
5 int main(void)
6 {
7 union{
8 int n;
9 char c[4];
10 };
11
12 n = 0x12345678;
13 printf("%x,%x,%x,%x\n",c[0],c[1],c[2],c[3]);
14
15 return 0;
16 }
3)枚举
A:在声明枚举类型的变量时不用再使用enum关键字
B:枚举不再是一种整数类型,是一种独立的类型
1 #include <iostream>
2 using namespace std;
3
4 int main(void)
5 {
6 enum E{a,b,c,d};
7 int n = a;//枚举可以转换成整数
8 E e = 10;//错误,整数不能给枚举赋值,只能用a,b,c,d赋值
9 cout << "n=" << n << endl;
10 return 0;
11
12 }
1.7) C++中的bool类型
typedef int BOOL
#define TRUE 1
#define FALSE 0
1 #include <iostream>
2
3 using namespace std;
4
5 int main(void)
6 {
7 bool b=true;
8 cout << b << endl;
9 b=!b;
10 cout << b << endl;
11 cout << sizeof(bool) << endl;
12 b=10;
13 cout << b << endl;
14 return 0;
15 }
~
bool类型用1个字节来存储
1.8 C++中运算符转换
C C++ 解释
---------------------------
&& and 逻辑与
|| or 逻辑或
! not 逻辑非
& bitand 按位与
| bitor 按位或
~ compl 按位取反
^ xor 异或
1.9 C++中的函数
1)函数的重载
在同一个作用域下,函数名是相同的,参数表 不同的若干个函数。
语法:
返回值 函数名(参数表)----编译器是通过 参数表不同 来区分 不同的函数。
对于重载函数,编译器会做改名的工作。-----------深刻理解
对于C语言的函数在C++中使用要加:extern "C" { },这样在处理的时候就不会进行换名的工作。
1 #include <iostream>
2 using namespace std;
3 int add(int a,int b)
4 {
5 cout << "int add("<< a << ',' << b << ")" << endl;
6 return a+b;
7 }
8 double add(double a,double b)
9 {
10 cout << "dboule add(" << a << ',' << b << ")" << endl;
11 return a+b;
12 }
13
14 double add(double a,int b)
15 {
16 cout << "dboule add(" << a << ',' << b << ")" << endl;
17 return a+b;
18 }
19 int main(void)
20 {
21 int a=2,b=3,f=5;
22 double c=2.1,d=3.2;
23 double e=2.3;
24 cout << add(a,b) << endl;
25 cout << add(c,d) << endl;
26 cout << add(e,f) << endl;
27 return 0;
28 }
songxl@ubuntu:~/cpp/day01$ nm a.out
0804a040 B __bss_start
0804a0cc b completed.6590
U __cxa_atexit@@GLIBC_2.1.3
0804a038 D __data_start
0804a038 W data_start
080486c0 t deregister_tm_clones
08048730 t __do_global_dtors_aux
08049f04 t __do_global_dtors_aux_fini_array_entry
0804a03c D __dso_handle
08049f0c d _DYNAMIC
0804a040 D _edata
0804a0d0 B _end
08048aa4 T _fini
08048ab8 R _fp_hw
08048750 t frame_dummy
08049efc t __frame_dummy_init_array_entry
08048c90 r __FRAME_END__
0804a000 d _GLOBAL_OFFSET_TABLE_
08048a14 t _GLOBAL__sub_I__Z3addii
w __gmon_start__
08048594 T _init
08049f04 t __init_array_end
08049efc t __init_array_start
08048abc R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
08049f08 d __JCR_END__
08049f08 d __JCR_LIST__
w _Jv_RegisterClasses
08048aa0 T __libc_csu_fini
08048a30 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
080488f3 T main
080486f0 t register_tm_clones
08048680 T _start
0804a040 D __TMC_END__
080486b0 T __x86.get_pc_thunk.bx
080487ef T _Z3adddd//对应add(double a,double b)
08048877 T _Z3adddi//对应add(double a,int b)
0804877d T _Z3addii//对应add(int a,int b)
080489d5 t _Z41__static_initialization_and_destruction_0ii
U _ZNSolsEd@@GLIBCXX_3.4
U _ZNSolsEi@@GLIBCXX_3.4
U _ZNSolsEPFRSoS_E@@GLIBCXX_3.4
U _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4
U _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4
0804a040 B _ZSt4cout@@GLIBCXX_3.4
U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4
0804a0cd b _ZStL8__ioinit
U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c@@GLIBCXX_3.4
U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4
songxl@ubuntu:~/cpp/day01$
2)缺省参数
A:给参数设定一个默认值;
B:原则只能说函数从右边向左来设置默认值,中间必须是连续的 有默认值。
C:如果是声明和定义分开的情况,声明可以定义默认值,定义中不再指定默认值。
1 #include <iostream>
2 using namespace std;
3
4 void foo(int i=1,float f=3.14,double d=2.2)
5 {
6
7 cout << i <<" "<< f<<" " << d << endl;
8 }
9 /*
10 void foo(int n)
11 {
12
13 cout << i << endl;
14 }
15 */
16 void fun(char c,int n=10);//描述中n已经有默认值
17 int main(void)
18 {
19
20 foo(10,2.12,4.56);
21 foo(20,2.12);
22 foo();
23 fun('c');
24 return 0;
25 }
26 void fun(char c,int n)//定义中n不设置默认值。
27 {
28
29 cout << c << " " << n << endl;
30 }
3)哑元
只有类型,没有参数名的参数叫哑元
哑元的作用为:
A:向下兼容
B:实现重载
1 #include <iostream>
2 using namespace std;
3 void foo(int n,int)
4 {
5 cout << n << 10 << endl;
6 }
7
8 void foo(int n)
9 {
10 cout << n << endl;
11 }
12 int main(void)
13 {
14 foo(20,3);//说明向下兼容
15 foo(30);//说明函数重载
16 return 0;
17 }
songxl@ubuntu:~/cpp/day01$ a.out
2010
30
4)内联函数--只适用于代码量比较小的情况
#define CIRCLE(R) (3.14*(R)*(R)) //在C语言中一定要加括号,括号括号。
//为什么要加括号呢?因为传进来的R有可能是一个表达式。
A宏替换发生在编译之前,是简单的字符串替换。没有类型检查
B内联函数替换发生在编译之后的二进制代码的替换。
C内联函数有类型检查;用起来比宏更安全
D隐式声明---函数放到类声明中去实现
显式声明---在普通函数前面加关键字inline
E内联函数是用空间换时间,加了inline关键字的函数不一定会编译成内联函数
1 #include <iostream>
2 using namespace std;
3 #define CIRCLE(R) (3.14*(R)*(R))//宏替换
4 inline double circle(double r){//内联函数
5 return 3.14*r*r;
6 }
7 int main(void)
8 {
9 double r = 3.5;
10 cout << CIRCLE(r) << endl;
11 cout << circle(r) << endl;
12 return 0;
13 }
~
1.10 C++中的内存分配
C语言中的内存分配:
malloc/calloc/realloc
free
C++中的内存分配:
new/delete
C语言中的指针
int *p;//指针
int *p[4];//指针数组-------数组中每一个元素都是指针
int (*p)[4];//数组指针-----指向一个4个元素的数组
int *p(); //函数;其返回值是一个指针
int (*p)();//函数指针
1 #include <iostream>
2 #include <cstdlib>
3 using namespace std;
4 int main(void)
5 {
6 //c中的内存分配
7 int *p = (int *)malloc(sizeof(int));//
8 if (p)
9 {
10 *p=100;
11 cout << *p << endl;
12 }
13 free(p);//释放指针
14 p=NULL;//用完之后,再把指针置成空,防止成为野指针
15
16 //c++的内存分配
17 p = new int (200);//p存储的值是200,分配内存,并将p初始化为200
18 //分配的空间大小是根据int类型来决定的。
19 cout << *p << endl;
20 delete p;//释放指针,指针里面的值还是有的。
21 p=NULL;//置空
22 //分配数组
23 p = new int[4];//分配4个int大小的空间;
24 for (int i = 0; i < 4;i++)
25 {
26 cout << p[i]<< " ";
27 }
28 cout << endl;
29 delete []p;
30 cout << "--------------------------------" << endl;
31 //p = NULL;//这样的话只能释放数组的第一个元素
32
33 //二维数组分配 a[][]
34 //二维数组的指针 返回的就是一个行指针
35 int (*pp)[4] = new int[4][4];
36 for (int i = 0; i < 4; i++)
37 {
38 for (int j = 0;j < 4; j++)
39 {
40 cout << pp[i][j]<<" ";
41 }
42 cout << endl;
43 }
44 delete []pp;
45
46 cout << "----------------------------------" << endl;
47
48 //定位分配,从已有的分配的内存空间中再分配一块出来
49 char * buf = new char[100];
50 int * pn = new(buf) int[10];
51 delete []buf;
52 return 0;
53 }
songxl@ubuntu:~/cpp/day01$ a.out
100
200
0 0 0 0
--------------------------------
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
----------------------------------
C++复习笔记一
最新推荐文章于 2024-09-10 17:35:48 发布