C++学习笔记

【声明:版权所有,欢迎转载】

1、c++引入命名空间是为了避免发生冲突问题。  A::a,B::a

2、 iostream.h 非标准的输入/输出头文件,是C格式的;iostream标准输入/输出头文件是C++格式的。

3、在程序中要使用自己定义的函数,则必须先声明它,然后定义它。声明的目的是告诉编译器将要定义这个函数的名字、类型及参数,在内存中并为这个函数分配内存定义是告诉编译器这个函数的功能,在内存中给这个函数分配内存

4、在函数内部声明的变量为局部变量,局部变量是这个变量只存活在这个函数中,当函数调用结束,该变量的寿命也结束了。

5、在任一函数外部定义的变量为全局变量,这种变量对程序中的任何函数均有效。

6、常量const)表示它的值是不可改变的,而变量的值是可以改变的。定义变量之后,系统便会为这个变量分配一个内存地址

7、所有的变量都在内存中生成,内存与硬盘不同,数据和变量不能永久地保存在内存上,当程序结束或断电后,这些数据或变量便释放或者丢失。

8、奇校验规定正确的代码中一个字节(8个二进制位)中1的个数必须是奇数,若非奇数,则在最高位添1偶校验规定正确的代码中一个字节中1的个数必须是偶数,如非偶数,则在最高位添1.

9、反斜杠‘\’改变了其后字母的含义,因此它又叫转义字符

10、利用枚举型常量,可以用文字替代数字,使程序变得更加易懂。如:enum num {zero,one,two,three,four}

11、运算符:加( +)、减(-)、乘(*)、除( /)、取模(%)。

12、后置 a++a--,表示在取值之后先进行自加或自减。

13、前置 ++a,  --a表示在取值之前先进行自加或自减。

14、三目运算符z=(a>b) ? ab,表示,如果?左边表达式为真,则a, 否则取b.

15、面向对象的四个特征:抽象、封装、继承、多态。Class Human{};

16、是一个抽象的名词,而对象则是实际的个体。Human Mike;

17、对象与成员的关系:Mike.weight=100; 不要给类赋值,如Human.weight=100;

18、Public 可以将类的成员说明为共有,即可以被该类的所以成员访问。Private将类成员说明为私有(类calss默认为私有,结构体stuct默认为共有),类成员不能被对象直接访问,只能通过在类中设置接口函数来访问

19、使用私有+接口函数,是为了提高代码的安全性,防止造成错误的输入和输出,各个对象不能直接访问并修改数据。一般情况下我们可将类的数据成员设置为私有,使用类的共有函数来访问他们

20、我们可以将类的声明和定义保存在头文件中(.h),将程序的执行部分放在源文件中(.cpp),在需要的源文件顶部包含相应的头文件即可。

21、在编程时,对于不应当改变对象的数据成员的成员函数,都应该声明或定义为const成员函数

22、在创建一个对象时,系统会自动调用该类的构造函数,初始化这个对象的状态;在类的对象被销毁后,系统会调用该类的析构函数,来清除它所占用的内存。

23、循环语句的前身----goto  语句,可以无条件转跳到某条语句执行。(慎用goto语句)

24、While语句 ,whilea<100 && a>0)。

25、Continue 语句只跳出本次循坏,而是跳转到循环的开头处执行下一次循环,而break 语句跳出所有循环,但并不退出程序,循环后面的语句照样进行。

26、Swith ----case 语句 要用break 

27、Cout<<&i<<endl; 通过&符号获取i在内存中的地址。

28、指针就是用来保存内存地址的变量,因此定义一个指针后一定要先赋值为NULL。不然就是一个迷途指针,会造成意想不到的后果。

29、Int a=1; int *p; p=&a; cout<<*p; 结果输出 1*被称为指针运算符,指针变量前加*表示“存储在此地址处的值”。

30、为什么要用指针?答:在操作大型数据和类时,由于指针可以通过内存地址直接访问数据,可避免在程序中复制大量的代码,因此指针的效率最高指针三大用途:(1)处理中存放的大型数据;(2)快速访问类的成员数据和函数;(3)以别名的形式向函数传递参数。

31、数据在内存中的存放形式有以下几种:

  (1栈区(stack)(先进后出)-------由编译器自动分配并且释放,该区域一般存放函数的参数值局部变量的值等。

  (2堆区(heap------一般由程序员分配及释放,若不释放,程序结束时可能由操作系统回收(但可能引起内存泄露)。

  (3)   寄存器区 -----------用来保存栈顶指针和指令指针。

  (4全局区(静态区)(static-------全局变量和静态变量是存储在一起的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域。程序结束后由系统释放。

  (5文字常量区-----存放常量字符串,程序结束后由系统释放。

  (6)  程序代码区-----存放函数体的二进制代码。

32、栈和堆的总结:

  (1的内存小,但是效率高,不过存储的数据只能在局部有效,超出局部就消失了。

  (2的可存储空间可以非常大,但是容易产生内存碎片,效率也较低,其优点是灵活性比较高。

33、int *p=new int; delete p;  这将释放指针所指向的内存,而不会释放指针,因此,你还可以使用该指针。将p=0; delete p;这样就不会出错。

34、指针变量只能保存一个地址,如对它重新赋值,则表示以前的地址被覆盖,假如该地址的内存没有被释放,那么你将无法再次通过指针P访问,那么就会造成内存泄露,如:int *p=new int; p=new int

35、对象在栈中和在堆中有所不同

   (1)在栈中的对象,在超出作用域时,比如遇到右大括号时,就会自动调用析构函数来释放该对象所占用的内存。

   (2)在堆中的对象,需要程序员自行释放其所占用的内存,否则该对象所占用的内存会在程序结束才被系统回收。

36、this指针就是指向当前对象的指针,在默认情况下,this指针可以省略不写。

37、指针的运算;

  (1) 指针的加减运算-----int型,指针的加运算就是指针指向的内存地址增加4个字节。

2)指针的赋值运算----将一个指针变量的地址赋给另一个指针变量。

 (3)指针的比较运算

38、常量指针(int *const p----指针指不可更改,但是其空间指向的值是可以改变的。

39、指向常量的指针const int *p-----指针可以修改,但是指针指向的整型变量不可更改。

40、指向常量的常指针const int *const p----指针不可以修改,并且指针指向的整型变量不可更改。

41、引用----即某个变量的别名,对原值的操作和对引用的操作都是一样的效果。定义引用时一定要对该引用进行初始化(只能初始化,不能赋值)。如:int a ; int &ra=a; 但是下面的是错误的:int a;int &ra; ra=a; 

42、函数参数的传递

   (1)按值传递---- void get( int a;int b);  会产生参数的副本  

   (2)按地址传递----void get(int *a, int *b);   直接引用

   (3)按别名传递----void get(int &a,int &b);   直接引用   按别名传递比按地址传递清晰

43、当函数需要返回多个值时,可以用指针或者引用来解决。使用别名或者指针的方式给函数传递多个参数,在函数中将需要返回的值赋给这些变量。

44、传递对象

1)按值传递对象----仍然会产生该对象的副本,假如对象的数据非常多,那么内存开销很多。

2)利用指针来传递对象----A *func(A *one) 没有复制 ,但是 A func(A *one),由于它返回的是对象而不是该对象的内存地址,仍然有复制。

3)利用const指针来传递对象----const A*const func(const A*const one),这样函数接收和返回的对象都是不可修改的,指向返回值的指针也是不可修改的。

4)利用引用来传递对-----如果不在参数的类型前加const,那么引用的值被修改后,被引用的值也会被修改。

45、为了避免指针混乱,“在哪里创建,就在哪里释放”指针。如:在main中创建了一个堆中对象,然后按引用的方式传递到func()函数中,在func()函数中对该对象操作完毕后返回对象,然后在main函数中释放该对象。

46、函数的重载。

47、由于常量和引用只能被初始化,不能被赋值,因此最好在构造函数中对常量和引用进行初始化

48、在创建某个类的对象时,首先调用该类的构造函数初始化对象,然后才对该对象的每个成员变量进行初始化,初始化的顺序是按照类中每个成员变量的说明顺序。

49、定义变量时一定要进行初始化,避免未初始化的变量引起运行错误。同样,在定义常量时,也必须初始化。

50、变量的定义用于为变量分配存储空间,还可以为变量指定初始值,一个程序中,变量有且仅有一个定义。

变量的声明用于向程序表明变量的类型和名字。定义也是声明:当定义变量时我们声明了它的类型和名字。可以通过使用extern关键字声明变量名而不定义它。Extern声明不是定义,也不分配内存空间。

全局作用域的变量时定义在该对象的文件的局部变量,此变量只存在于那个文件中,不能被其他文件访问,但是通过extern就可以在整个程序中访问该对象。如:extern int num

51、通常将一个对象定义在它首次使用的地方时一个很好的方法。(提高程序的可读性)

52、在实际程序中,引用主要作用于函数的形式参数

53、区别define 和typedef 的具体区别。#define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不管含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错;typedef是在编译时处理的。它在自己的作用域内给一个已经存在的类型一个别名。

54、枚举。enum open_modes {intput, output,apend };默认第一个成员为0,后面依次加1

显示初始化枚举成员。如:enum forms {shape=1,sphere, cylinder,polygon };

55、从操作开始设计类。定义类时,通常先定义该类的接口,即该类所提供的操作,通过这些操作,可以决定该类完成其功能所需要的数据,以及是否需要定义一些函数来支持该类的实现。这些操作和数据时类的一部分,也称为类的成员, 操作称为成员函数,数据称为数据成员。

56、Class 和 struct 关键字定义类的唯一差别在于默认访问级别:在默认情况下,struct的成员为public ,而class 的成员为private 

57、头文件为相关声明提供了一个集中存放的位置。头文件一般包括类的定义、extern 变量的声明和函数的声明。头文件用于声明而不是用于定义。(定义只能出现一次,而声明可以出现多次)。因为头文件包含在多个源文件中,所以不应该包含有变量或函数的定义(3例外:可以定义、值在编译时就知道的const象和inline函数)。如果const 变量不是用常量表达式初始化,那么它就不应该在头文件中定义,相反,和其他的变量一样,该const变量应该在一个源文件中定义并初始化,应在头文件总为它调价extern声明,以使其能被多个文件访问(在源文件中,#include 该头文件)。

58、头文件保护符:一个文件经常被多次包含进同一个源文件,这时,就应该保护该多次包含的头文件不被多次定义和声明。

 #ifndef   SALESITEM_H

 #define  SALESITEM_H

 ........

 #endif

59、#include  <iostream>和 #include  my_life.h的区别:尖括号(<>)被认为该头文件是标准头文件,编译器会在预定的位置集查找该头文件,引号(“”)被认为是非系统头文件,编译器会在源文件所在目录下查找。

60、几种初始化string对象的方法:

string s1;            //默认构造函数,s1为空串

String s2(s1);        //s2初始化s1的一个副本

String s3(“value”);    //s3初始化为一个字符串字面值副本

String s4(n,’c’); //将初始化为字符’c’的n个副本

61、string对象的加法被定义为连接。String s3+=s1;String s3+=”  ”;

62、vector 不是一种数据类型,而只是一个类模板,可用来定义任意多种数据类型。Vector类型的每一种都定义了其保存元素的类型,因此,vector<int>vectoer<string>都是数据类型。虽然可以对给定元素个数的vector对象预先分配内存,但更有效的方法是先初始化一个空的vector对象,然后再动态地增加元素。

63、显示初始化数组元素;如:

Const unsigned array_size=3;

Int ia[array_size]={0,1,2};(元素个数不能超过维数)

显示初始化的数组不需要指定数组的维数值,编译器会根据列出的元素个数来却动数组的长度。如:int ia[]={0,12,1,3};

如果元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显示初始化

64、理解指针声明语句时,请从右向左阅读。

65、void* 指针是一种特殊的指针类型,它可以保存任何类型对象的地址,即表明该指针与一地址值相关,但不清楚存储在该地址上的对象类型。

66、给指针赋值或通过指针进行赋值;

如果对左操作数进行解引用(*操作符),则修改的是指针指向对象的值;

如果没有使用引用操作,则修改的是指针本身的值。

67、引用与指针有两个重要区别:

第一:引用总是指向某个对象(引用一经初始化,就始终指向同一个特定对象),定义引用时没有初始化是错误的;

第二:给引用赋值修改的是该引用所关联的对象的值,而并不是使引用与另一个对象关联;

68、在实际的程序中,指向const的指针常用作函数的形参,以确保传递给函数的实际对象在函数中不因为形参而被修改。如:void edgeThread(IplImage*  &result, const IplImage*  edge,const IplImage*  mode,const IplImage*  test,double  threshold){ }。

69、C语言程序使用一对标准库函数malloc和 free在自由存储区()中分配存储空间,而C++语言则使用new和delete表达式实现相同的功能。

70、不应该串接使用关系操作符。如:if(5<i<10)是错误的,应该是if(i<10 && i>5).

71、空语句:如果在程序的某个地方,语法上需要一个语句,但逻辑上并不需要,这时就可以使用空语句。(使用空语句要加上注释)

72、Switch结构,注意不要忘记break语句。

73、函数调用做了两件事:用对应的实参初始化函数的形参,并将控制权转移给被调用函数。主调函数的执行被挂起,被调函数开始执行。每次调用函数时,都会重新创建该函数所有的形参,此时所传递的实参将会初始化对应的形参。

74、函数形参表可以为空,但不能省略。

75、函数的参数传递:

(1)、非引用形参

普通的非引用类型的参数通过复制对应的实参实行初始化。当实参副本初始化形参是,函数并没用访问调用所传递的实参本身,不会修改实参的值。

A、指针形参

此时复制实参指针,与其他非引用类型的形参一样,该类形参的任何改变也仅作用于局部副本。

Bconst形参

如果该函数使用非引用的非const形参,则既可以给该函数传递const实参,也可以传递非const的实参。

C、复制实参的局部性

当需要在函数中修改实参的值时;

当需要以大型对象作为实参传递时;对实际的引用而言,复制对象所付出的时间和存储空间代价往往过大;

当没有办法实现对象的复制时;

对于上述几种情况,有效的解决办法是将形参定义为引用或指针类型

(2)、引用形参

引用形参直接关联到其所绑定的对象,而并非这些对象的副本。每次调用函数,引用形参被创建并与相应实参关联。

A、使用引用形参返回额外的信息

当我们需要函数返回多个值时,就可以使用引用形参。

B、利用const引用避免复制

当向函数传递大型对象时,需要使用引用形参,避免复制大量数据,提高效率。

C、更灵活的指向const的引用

D、传递指向指针的引用,如:void ptrswap(int *&v1,int *&v2){ };

76、千万不要返回局部对象的引用(同理,不要返回指向局部对象的指针)

当函数执行完时,将释放分配给局部对象的存储空间。此时,对局部对象的引用就会指向不确定的内存。如:

Const string &manip(const sting &s)

{

String ret=s;

return ret; 

}

77、不管我们是从控制窗口磁盘文件内存中的字符串读入数据,都可以使用>>操作符,相似的,不管我们读的是char类型的字符还是wchar_t类型的字符,也可以使用该操作符。

78、IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于读写存储在内存中的string对象。

79、类背后蕴含的基本思想是数据抽象与封装

80、当我们定义一个类的对象时,编译器分配了足以容纳一个该类对象的存储空间,每个对象具有自己的类数据成员的副本,修改一个对象的成员数据不会改变任何其他的类对象的数据成员。



参考资料:

《C++ Primer》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值