C++知识点

C++知识点总结 过两天就要考C++了,这次一点都不慌张和害怕,虽然看书、做题、总结也就5、6天的时间,但三遍读书法算是比较完整的过了一遍,模拟成绩也还不错,希望能够取得好成绩。O(∩_∩)O~           看了两本书,自考课本(编号04737)和C++程序设计谭浩强版的,我比较推荐后一本,浅显易懂,知识点多,例子多,可以自己多多动手写一写。 下面对学习过程中需要注意的知识点做了一些总结和导图: 阅读详情
 

一、#include "filename.h"和#include 的区别

#include "filename.h"是指编译器将从当前工作目录上开始查找此文件

#include 是指编译器将从标准库目录中开始查找此文件

二、头文件的作用

加强安全检测

通过头文件可能方便地调用库功能,而不必关心其实现方式

三、* , &修饰符的位置

对于*和&修饰符,为了避免误解,最好将修饰符紧靠变量名

四、if语句

不要将布尔变量与任何值进行比较,那会很容易出错的。

整形变量必须要有类型相同的值进行比较

浮点变量最好少比点,就算要比也要有值进行限制

指针变量要和NULL进行比较,不要和布尔型和整形比较

五、const和#define的比较

const有数据类型,#define没有数据类型

个别编译器中const可以进行调试,#define不可以进行调试

在类中定义常量有两种方式

1、 在类在声明常量,但不赋值,在构造函数初始化表中进行赋值;

2、 用枚举代替const常量。

六、C++函数中值的传递方式

有三种方式:值传递(Pass by value)、指针传递(Pass by pointer)、引用传递(Pass by reference)

void fun(char c) //pass by value

void fun(char *str) //pass by pointer

void fun(char &str) //pass by reference

如果输入参数是以值传递的话,最好使用引用传递代替,因为引用传递省去了临时对象的构造和析构

函数的类型不能省略,就算没有也要加个void

七、函数体中的指针或引用常量不能被返回

Char *func(void)

{

char str[]="Hello Word";

//这个是不能被返回的,因为str是个指定变量,不是一般的值,函数结束后会被注销掉

return str; 

}

函数体内的指针变量并不会随着函数的消亡而自动释放

八、一个内存拷贝函数的实现体

void *memcpy(void *pvTo,const void *pvFrom,size_t size)

{

assert((pvTo!=NULL)&&(pvFrom!=NULL));

byte *pbTo=(byte*)pvTo; //防止地址被改变

byte *pbFrom=(byte*)pvFrom;

while (size-- >0)

pbTo++ = pbForm++;

return pvTo;

} 

九、内存的分配方式

分配方式有三种,请记住,说不定那天去面试的时候就会有人问你这问题

1、 静态存储区,是在程序编译时就已经分配好的,在整个运行期间都存在,如全局变量、常量。

2、 栈上分配,函数内的局部变量就是从这分配的,但分配的内存容易有限。

3、 堆上分配,也称动态分配,如我们用new,malloc分配内存,用delete,free来释放的内存。

十、内存分配的注意事项

用new或malloc分配内存时,必须要对此指针赋初值。

用delete 或free释放内存后,必须要将指针指向NULL

不能修改指向常量的指针数据

十一、内容复制与比较

//数组......

char a[]="Hello Word!";

char b[10];

strcpy(b,a);

if (strcmp(a,b)==0)

{}

//指针......

char a[]="Hello Word!";

char *p;

p=new char[strlen(a)+1];

strcpy(p,a);

if (strcmp(p,a)==0)

{}

十二、sizeof的问题

记住一点,C++无法知道指针所指对象的大小,指针的大小永远为4字节

char a[]="Hello World!"

char *p=a;

count<

count<

而且,在函数中,数组参数退化为指针,所以下面的内容永远输出为4

void fun(char a[1000])

{

count<

}

十三、关于指针

1、 指针创建时必须被初始化

2、 指针在free 或delete后必须置为NULL

3、 指针的长度都为4字节

4、释放内存时,如果是数组指针,必须要释放掉所有的内存,如

char *p=new char[100];

strcpy(p,"Hello World");

delete []p; //注意前面的[]号

p=NULL;

5、数组指针的内容不能超过数组指针的最大容易。

如:

char *p=new char[5];

strcpy(p,"Hello World"); //报错 目标容易不够大

delete []p; //注意前面的[]号

p=NULL;

十四、关于malloc/free 和new /delete

l malloc/free 是C/C+的内存分配符,new /delete是C++的内存分配符。

l 注意:malloc/free是库函数,new/delete是运算符

l malloc/free不能执行构造函数与析构函数,而new/delete可以

l new/delete不能在C上运行,所以malloc/free不能被淘汰

l 两者都必须要成对使用

l C++中可以使用_set_new_hander函数来定义内存分配异常的处理

十五、C++的特性

C++新增加有重载(overload),内联(inline),Const,Virtual四种机制

重载和内联:即可用于全局函数,也可用于类的成员函数;

Const和Virtual:只可用于类的成员函数;

重载:在同一类中,函数名相同的函数。由不同的参数决定调用那个函数。函数可要不可要Virtual关键字。和全局函数同名的函数不叫重载。如果在类中调用同名的全局函数,必须用全局引用符号::引用。

覆盖是指派生类函数覆盖基类函数

函数名相同;

参数相同;

基类函数必须有Virtual关键字;

不同的范围(派生类和基类)。

隐藏是指派生类屏蔽了基类的同名函数相同

1、 函数名相同,但参数不同,此时不论基类有无Virtual关键字,基类函数将被隐藏。

2、 函数名相同,参数也相同,但基类无Virtual关键字(有就是覆盖),基类函数将被隐藏。

内联:inline关键字必须与定义体放在一起,而不是单单放在声明中。

Const:const是constant的缩写,"恒定不变"的意思。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

1、 参数做输入用的指针型参数,加上const可防止被意外改动。

2、 按值引用的用户类型做输入参数时,最好将按值传递的改为引用传递,并加上const关键字,目的是为了提高效率。数据类型为内部类型的就没必要做这件事情;如:

将void Func(A a) 改为void Func(const A &a)。

而void func(int a)就没必要改成void func(const int &a);

3、 给返回值为指针类型的函数加上const,会使函数返回值不能被修改,赋给的变量也只能是const型变量。如:函数const char*GetString(void); char *str=GetString()将会出错。而const char *str=GetString()将是正确的。

4、 Const成员函数是指此函数体内只能调用Const成员变量,提高程序的键壮性。如声明函数 int GetCount(void) const;此函数体内就只能调用Const成员变量。

Virtual:虚函数:派生类可以覆盖掉的函数,纯虚函数:只是个空函数,没有函数实现体;

十六、extern"C"有什么作用?

Extern "C"是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数。这是因为C++编译后库中函数名会变得很长,与C生成的不一致,造成C++不能直接调用C函数,加上extren "c"后,C++就能直接调用C函数了。

Extern "C"主要使用正规DLL函数的引用和导出 和 在C++包含C函数或C头文件时使用。使用时在前面加上extern "c" 关键字即可。

十七、构造函数与析构函数

派生类的构造函数应在初始化表里调用基类的构造函数;

派生类和基类的析构函数应加Virtual关键字。

不要小看构造函数和析构函数,其实编起来还是不容易。

#include 

class Base

{

public: 

virtual ~Base() { cout<< "~Base" << endl ; }

};

class Derived : public Base

{

public: 

virtual ~Derived() { cout<< "~Derived" << endl ; }

};

void main(void)

{

Base * pB = new Derived; // upcast

delete pB;

}

输出结果为:

~Derived

~Base

如果析构函数不为虚,那么输出结果为

~Base

十八、#IFNDEF/#DEFINE/#ENDIF有什么作用

仿止该头文件被重复引用

C语言之指针 数组 函数

  基本解释

  1、指针的本质是一个与地址相关的复合类型,它的值是数据存放的位置(地址);数组的本质则是一系列的变量。

  2、数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。指针可以随时指向任意类型的内存块,它的特征是"可变",所以我们常用指针来操作动态内存。

  3、当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。

  问题:指针与数组

  听说char a[]与char *a是一致的,是不是这样呢?

  答案与分析:

  指针和数组存在着一些本质的区别。当然,在某种情况下,比如数组作为函数的参数进行传递时,由于该数组自动退化为同类型的指针,所以在函数内部,作为函数参数传递进来的指针与数组确实具有一定的一致性,但这只是一种比较特殊的情况而已,在本质上,两者是有区别的。请看以下的例子:char a[] = "Hi, pig!"; char *p = "Hi, pig!";

 

  上述两个变量的内存布局分别如下:

  数组a需要在内存中占用8个字节的空间,这段内存区通过名字a来标志。指针p则需要4个字节的空间来存放地址,这4个字节用名字p来标志。其中存放的地址几乎可以指向任何地方,也可以哪里都不指,即空指针。目前这个p指向某地连续的8个字节,即字符串"Hi, pig!"。

  另外,例如:对于a[2]和p[2],二者都返回字符‘i',但是编译器产生的执行代码却不一样。对于a[2],执行代码是从a的位置开始,向后移动2两个字节,然后取出其中的字符。对于p[2],执行代码是从p的位置取出一个地址,在其上加2,然后取出对应内存中的字符。

  问题:数组指针

  为什么在有些时候我们需要定义指向数组而不是指向数组元素的指针?如何定义?

  答案与分析:

  使用指针,目的是用来保存某个元素的地址,从而来利用指针独有的优点,那么在元素需要是数组的情况下,就理所当然要用到指向数组的指针,比如在高维需要动态生成情况下的多维数组。

  定义例子如下: int (*pElement)[2]。

  下面是一个例子: int array[2][3] = {{1,2,3},{4,5,6}};

int (*pa)[3]; //定义一个指向数组的指针

pa = &array[0]; // '&'符号能够体现pa的含义,表示是指向数组的指针

printf ("%d", (*pa)[0]); //将打印array[0][0],即1

pa++; // 猜一猜,它指向谁?array[1]?对了!

printf ("%d", (*pa)[0]); // 将打印array[1][0],即4

 

  上述这个例子充分说明了数组指针—一种指向整个数组的指针的定义和使用。

  需要说明的是,按照我们在第四篇讨论过的,指针的步进是参照其所指对象的大小的,因此,pa++将整个向后移动一个数组的尺寸,而不是仅仅向后移动一个数组元素的尺寸。

  问题:指针数组

  有如下定义:struct UT_TEST_STRUCT *pTo[2][MAX_NUM];

  请分析这个定义的意义,并尝试说明这样的定义可能有哪些好处?

  答案与分析:

  前面我们谈了数组指针,现在又提到了指针数组,两者形式很相似,那么,如何区分两者的定义呢?分析如下:

  数组指针是:指向数组的指针,比如 int (*pA)[5]。

  指针数组是:指针构成的数组,比如int *pA[5]。

  至于上述指针数组的好处,大致有如下两个很普遍的原因:

  a)、各个指针内容可以按需要动态生成,避免了空间浪费。

  b)、各个指针呈数组形式排列,索引起来非常方便。

  在实际编程中,选择使用指针数组大多都是想要获得如上两个好处。

  问题:指向指针的指针

  在做一个文本处理程序的时候,有这样一个问题:什么样的数据结构适合于按行存储文本?

  答案与分析:

  首先,我们来分析文本的特点,文本的主要特征是具有很强的动态性,一行文本的字符个数或多或少不确定,整个文本所拥有的文本行数也是不确定的。这样的特征决定了用固定的二维数组存放文本行必然限制多多,缺乏灵活性。这种场合,使用指向指针的指针有很大的优越性。

  现实中我们尝试用动态二维数组(本质就是指向指针的指针)来解决此问题:

  图示是一个指针数组。所谓动态性指横向(对应每行文本的字符个数)和纵向(对应整个文本的行数)两个方向都可以变化。

  就横向而言,因为指针的灵活性,它可以指向随意大小的字符数组,实现了横向动态性。

  就竖向而言,可以动态生成及扩展需要的指针数组的大小。

  下面的代码演示了这种动态数组的用途:

// 用于从文件中读取以 '\0'结尾的字符串的函数 

extern char *getline(FILE *pFile);

FILE *pFile;

char **ppText = NULL; // 二维动态数组指针 

char *pCurrText = NULL; // 指向当前输入字符串的指针

ULONG ulCurrLines = 0;

ULONG ulAllocedLines = 0;

while (p = getline(pFile))

{

 if (ulCurrLines >= ulAllocedLines)

 {

  // * 当前竖向空间已经不够了,通过realloc对其进行扩展。

  ulAllocedLines += 50; // 每次扩展50行。 

  ppText = realloc (ppText, ulAllocedLines * (char *));

  if (NULL == ppText)

  {

   return; // 内存分配失败,返回 

  }

 }

 ppText[ulCurrLines++] = p; // 横向"扩展",指向不定长字符串 

}


 

  问题:指针数组与数组指针与指向指针的指针

  指针和数组分别有如下的特征:

  指针:动态分配,初始空间小

  数组:索引方便,初始空间大

  下面使用高维数组来说明指针数组、数组指针、指向指针的指针各自的适合场合。

   多维静态数组:各维均确定,适用于整体空间需求不大的场合,此结构可方便索引,例a[10][40]。

   数组指针:低维确定,高维需要动态生成的场合,例a[x][40]。

   指针数组:高维确定,低维需要动态生成的场合,例a[10][y]。

   指向指针的指针:高、低维均需要动态生成的场合,例a[x][y]。

  问题:数组名相关问题

  假设有一个整数数组a,a和&a的区别是什么?

  答案与分析:

  a == &a == &a[0],数组名a不占用存储空间。需要引用数组(非字符串)首地址的地方,我一般使用&a[0],使用a容易和指针混淆,使用&a容易和非指针变量混淆。

  区别在于二者的类型。对数组a的直接引用将产生一个指向数组第一个元素的指针,而&a的结果则产生一个指向全部数组的指针。例如:int a[2] = {1, 2};

int *p = 0;

p = a; /* p指向a[0]所在的地方 */

x = *p; /* x = a[0] = 1*/

p = &a; /* 编译器会提示你错误,*/

/*显示整数指针与整数数组指针不一样 */

 

  问题:函数指针与指针函数

 

  请问:如下定义是什么意思:int *pF1(); int (*pF2)();

 

  答案与分析:

  首先清楚它们的定义:

   指针函数,返回一个指针的函数。

   函数指针,指向一个函数的指针。

  可知:

   pF1是一个指针函数,它返回一个指向int型数据的指针。

   pF2是一个函数指针,它指向一个参数为空的函数,这个函数返回一个整数。

C与C++代码精粹笔记二

1,预定义宏

__LINE__    当前代码行的行号(等于读到目前为止新行的字符数)

__FILE__    源文件的名字

__DATE__    以"Mmm dd yyyy"的形式转换日期

__TIME__    以"hh:mm:ss"的形式转换日期

__cplusplus    一个包含正式的C++标准的日期

2,如果代码是在C/C++混合编程环境中编写的,可以将新的C++代码与旧的C代码相链接。所需要做的所有事情就是通过extern "C"链接规范来告诉C++翻译器,不要"砍掉"与C组件相匹配的外部名字,例如:

extern "C" void  f();    // f() 在C环境下被编译

C++标准库中的C部分知道是否该砍掉名字(在第一章已解释过),这取决于在什么模式下(C或C++)编译。如果仔细阅读标准C头文件会发现销售商使用__cplusplus宏通过一个extern "C"块根据以下模式条件隐藏了标准C声明:

#if defined(__cplusplus)

extern "C"

{

#endif

#if defined(__cplusplus)

}

#endif

3,#if defined(X)  <==>  #ifdef X

defined运算符比其右边的等价指令要灵活多,因为可以把许多测试联合起来构成一个表达式:

#if defined(__cplusplus) && !defined(DEBUG)

4,预处理运算符

#    字符串化

##    加标记

defined    符号表查询

#define trace(x,format)    printf(#x "=%" #format "\n",x)

#define trace2(i) trace(x##i,d)

5,当宏必须作出选择时,好的做法是把它写成一个表达式而不是语句

void __assert(char *cond,char *fname,long lineno){

    fprintf(stderr,"Assertiion failed:%s, file %s, line %ld\n",cond,fname,lineno);

    abort();

}

#define assert(cond) \

    if(!(cond)) __assert(#cond,__FILE__,__LINE__)        //    不好

#define assert(cond) \

    ((cond)?(void)0:__assert(#cond,__FILE__,__LINE__)    // 好

    

6,预处理器的宏替换功能显而易见为你提供了很大的灵活性。但要记住以下两点限制:

A,无论何时预处理器在其替代文本中遇到当前的宏,不管在进程中有多么深的嵌套,它都不做扩展,只是保持不变(否则进程将永远不终止!)。

B,如果被充分扩展的语句相似于一条预处理指令(例如扩展以后结果是一条#include指令),它没有被调用,而是逐字地留在程序文本中。

7,三字符运算符序列

??= #

??( [

??/    \

??) ]

??'    ^

??< {

??! |

??> }

??- ~

8,新的C++双字符运算符和保留字

    }

<:    [

:>    ]

%%    #

Bitand    &

And        &&

Bitor    |

Or        ||

Xor        ^

Compl    ~

and_eq    &=

or_eq    |=

xor_eq    ^=

Not        !

not_eq    !=

9,翻译阶段

标准C和C++定义了9个不同的翻译阶段。当然,实现没有必要在代码中分成9个独立的阶段,但是翻译的结果必须好像已经这样做了一样,这9个阶段是:

1,物理源字符被映射到源字符集中。其中包括三字符组合替换以及诸如把回车/换行映射到一个单独的MSDOS环境下的换行字符那样的东西。在C++程序中,任何不在基础源字符集中的字符都被它的通用字符名替换。

2,所有以反斜杠结束的行都和它们接下来的行合并,并且删去反斜杠。

3,源码被分析成预处理标记,并且注释被一个单独的空字符所替换,C++双字符被识别为标记。

4,调用预处理指令并且扩展宏,对于任何被包含的文件循环地重复步骤1到4。

5,源字符退出字符常量序列,普通字符名被映射成执行字符集成员(例如,'\a'将在ASCII环境下转换成7的一个字节值)。

6,相邻的字符串被连接。

7,传统的编译:词汇和语义分析,并翻译成汇编语言或机器码。

8,(只有C++)执行任何待解决的模板实例。

9,链接:解决外部引用,准备好程序映像以便执行。

预处理器由步骤1到4组成。

10,存储两个指针差的便捷方法是把这个差存储在ptrdiff_t中,它在stddef.h中定义,包含在中。

ptrdiff_t diff=p-q;

11,说明指针转换

#include

using namespace std;

void main(){

    int i=7;

    char *cp=(char *)&i;

    

    cout<<"The integer at "<<&i<<" == "<    

    //分别打印每个字节的值

    for(int n=0;n        cout<<"The byte at "<<(void *)(cp+n)<<" == "<}

12,位域

#include

using namespace std;

struct Date{

    unsigned day:5;

    unsigned mon:4;

    unsigned year:7;

};

void main(){

    struct Date d;

    d.day=2;

    d.mon=8;

    d.year=92;

    cout<}

/////////////////////////////////////////////

#include

using namespace std;

struct Date{

    unsigned day:5;

    unsigned mon:4;

    unsigned year:7;

};

void main(){

    unsigned short date,year=92,mon=8,day=2;

    Date *dp=(Date *)&date;

    dp->day=day;

    dp->mon=mon;

    dp->year=year;

    cout<}

13,在面向对象操作中,指向一个对象的指针称为"句柄"。

14,普通指针

通常编写能接收指向任意类型参数的函数是很方便的。这是很有必要的,例如,用标准的库函数memcpy,能够从一个地址向另一个地址拷贝一块内存。你也可能想调用memcpy来拷贝自己创建的结构:

struct mystruct a,b;

...

memcpy(&a,&b,sizeof(struct mystruct));

为了操作任意类型的指针,memcpy把它头两个参数声明为void型指针。可以不需要强制类型转换将任何类型的指针赋予void*类型。也可以在C而不是C++中将void*赋予其他任何类型的指针。这里说明了void指针的memcpy函数的简洁实现:

void* memcpy(void* target, const void* source, size_t n){

    char *targetp=(char *)target;

    const char *sourcep=(const char *)source;

    while(n--)

    *targetp++=*sourcep++;

    return target;

}

这个版本的memcpy必须把指向void的指针赋予指向char指针一,这样它就可以每次传递内存块的一个字节,并对这个字节中的数据进行拷贝。试图复引用一个void*是没有意义的,因为它的大小是未知的。

15,

strncpy(s,t,n)[n]='\0';

a[i]=*(a+i)=*(i+a)=i[a]

size_t n=sizeof a/sizeof a[0];

cout<<(void*)"hello"p=a+n-1;

for(int i=0;i    cout<

16,函数指针

#include

void main(){

    int (*fp)(const char *,...)=printf;

    fp("hello\n");

}

17,

#include

#include

#include

using namespace std;

int comp(const void*, const void*);

void main(int argc, char *argv[]){

    qsort(argv+1, argc-1, sizeof argv[0], comp);

    while(--argc)

        cout<<*++argv<}

int comp(const void *p1, const void *p2){

    const char *ps1=*(const char **)p1;

    const char *ps2=*(char **)p2;

    return strcmp(ps1,ps2);

}

18,

#include

extern void retrieve(void);

extern void insert(void);

extern void update(void);

extern int show_menu(void);

void main(){

    int choice;

    void (*farray[])(void)={retrieve,insert,update};

    for(;;){

        choice=show_menu();

        if(choice>=1 && choice<=3)

            farray[choice-1]();

        else if(choice==4)

            break;

    }

}

19,

#include

using namespace std;

class Object{

public:

    void retrieve(){

        cout<<"Object::retrieve"<    }

    void insert(){

        cout<<"Object::insert"<    }

    void update(){

        cout<<"Object::update"<    }

    void process(int choice);

private:

    typedef void (Object::*Omf)();

    static Omf farray[3];

};

Object::Omf Object::farray[3]={&Object::retrieve,&Object::insert,&Object::update};

void Object::process(int choice){

    if(0<=choice && choice<=2)

        (this->*farray[choice])();

}

void main(){

    int show_menu();    // 您所提供的!

    

    Object o;

    

    for(;;){

        int choice=show_menu();

        if(1<=choice && choice<=3)

            o.process(choice-1);

        else if(choice==4)

            break;

    }

}

C与C++代码精粹笔记一

1,标准C允许非void类型指针和void类型指针之间进行直接的相互转换。但在C++中,可以把任何类型的指针直接指派给void类型指针,因为void*是一种通用指针;而不能反过来将void类型指针直接指派给任何非void类型指针,除非强制。

2,不可以直接把基类对象直接转换为派生类对象,无论是直接赋值还是强制转换,因为这是"不自然"的。对于基本类型的强制转换一定要区分值的截断与内存截断的不同。如果你是坚持要使用强制转换,必须同时确保内存访问的安全性和转换结果的安全性。

3,while(getch()!='a');        // 特定终止

4,在&&与||表达式中,如果计算前半部分的值后就能确定表达式的值,则表达式的后半部分不计算。

5,如果两个浮点数之差的绝对值小于或等于某一个可接受的误差(即精度),就认为它们是相等的,否则就是不相等。精度根据具体应用要求而定。因此不要直接用"=="或"!="对两个浮点数进行比较。

EPSILON=1e-6;

if(abs(x-y)<=EPSILON) ...        // equal

if(abs(x-y)>EPSILON) ...        // not equal

    if(abs(x)<=EPSILON)    ...        // equal 0

    if(abs(x)>EPSILON) ...         // not equal 0

6,    #define NULL ((void *)0)

    if(p==NULL)    ...

    if(p!=NULL) ...

7,在多重嵌套循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,这样可以减少CPU跨切循环层的次数,从而优化程序的性能。

for(col=0;col<5;col++){

    for(row=0;row<100;row++){

        sum+=a[row][col];

    }

}

8,如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体外面。

for(i=0;i<N;i++){

    if(condition)

        doSomething();

    else

        doOtherthing();

}

==>>

if(condition){

    for(i=0;i<N;i++)

        doSomething();

}else{

    for(i=0;i<N;i++)

        doOtherthing();

}

9,类中的枚举常量

class A{

    ...

    enum{SIZE1=100,SIZE2=200};

    int array1[SIZE1];

    int array2[SIZE2];

    ...

};

枚举常量不会占用对象的存储空间,它们在编译时被全部求值,更何况它定义的是一个匿名枚举类型。枚举常量的缺点是不能表示浮点数和字符串。还可以使用另一种方法来定义类的所有对象都共享的常量,即static const。

10,函数调用中参数传递的本质就是用来初始化形参而不是替换形参。

11,    char ch='a';

    printf("Address of ch:%p\n",&ch);

    

12,把任何类型的地址或指针强制转换成void *,就可以输出地址了。

13,标准C把空的参数列表解释为可以接受任何类型和个数的参数;而标准C++则把空的参数列表解释为不可以接受任何参数。

    void setValue(int width,int height);

    float getValue(void);

    

14,一般地,输出参数放在前面,输入参数放在后面,并且不要交叉出现。

15,应避免函数有太多的参数,参数个数尽量控制在5个以内。如果参数太多,在使用时容易将参数类型和顺序搞错。此时,可以将这些参数封装为一个对象并采用地址传递或引用传递方式。

16,标准C语言中,凡不加类型说明的函数,一律自动按int类型处理。

17,不要将正常值和错误标志混在一起返回。建议正常值用输出参数获得,而错误标志用return语句返回。

C++重要知识点精华总结                                  C++重要知识点精华总结cin的使用:1&gt;cin&gt;&gt;a;键盘读入数据赋值给a;1&gt;程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中取数据。2&gt;当cin&gt;&gt;从缓冲区中读取数据时,若缓冲区中第一个字符... 阅读详情

相关推荐

GESP C++ 各等级详细知识点汇总

函数声明与定义- 实参与形参,参数作用域- 参数传递方式:值传递、引用传递(

墨宸的博客 2449

C++中常用的位操作以及字节操作

位操作、字节操作。

lxthh611905的博客 486

C++算法竞赛入门常用知识点

C++算法竞赛入门常用知识点

无限进步 1262

C++内存管理

本文为学习侯捷老师的C++内存管理机制的笔记。 内存使用的接口等级 基本方法 new: 调用::operator new()->调用malloc开辟空间,如果空间不足,则调用用户注册的newhandler(一般用于释放空间),然后再开辟空间 将malloc开辟空间得到的指针,转为我们new的对象指针 利用对象指针调用其构造方法 delete: 调用析构 调用::operator delete()->调用free()释放空间 new ClassName[SIZE]: new数组,会

weixin_43367550的博客 351

C++面试知识点汇总

本博文是本文历时3个月,收集各种资料,汇总的C++面试题,欢迎各位博友评价。

zhangkkit的博客 5168

GESP C++ 一级知识点总结

GESP C++ 一级

qq_60918483的博客 4818

等长字符串的交叉连接 用指针实现的~~

可能指针用的不太地道,借鉴了数组的作用 #include #include #include void func(char *ps3,const char *ps1,const char *ps2); int main() { const char *ps1="Java",*ps2="Basi"; char str[200]; char *ps3; ps3=(

MOLIILOM的专栏 1471

光模块数字诊断监控(DDM)功能

DDM(Digital Diagnostic Monitoring)数字诊断监控,由行业组织SFF Committee制定,遵循SFF-8472多源协议定义的标准参数而工作,规范了光模块和网络设备的软硬件所需遵循的标准数值或范围,确保了网络设备供应商和光模块供应商之间所提供产品的互操作性不同。:通过监测激光器的偏置电流来预测激光器的劣化,从而确保在故障发生之前将业务切换到备用链路上或替换有可能故障的光模块,因此起到了预测光模块寿命的作用。光模块DDM信息可以通过SNMP读取光模块的接收光功率和发射光功率。.

光模块的博客 2300

char * parr = new char[10];是c语言吗,new和malloc的区别及内存管理及char[]与char*区别

1:new和malloc的区别 转载地址:http://www.cnblogs.com/fly1988happy/archive/2012/04/26/2470542.html1. malloc()函数1.1 malloc的全称是memory allocation,中文叫动态内存分配。原型:extern void *malloc(unsigned int num_bytes);说明:分配长度为nu...

weixin_31207903的博客 1000

小程序强制更新避坑指南:手把手教你实现无缝升级

本文详细解析小程序强制更新的实现方法,重点介绍wx.getUpdateManager API的使用技巧,帮助开发者规避冷热启动机制下的版本管理陷阱。通过实战案例展示如何设计多级更新提示策略,确保用户无缝升级,提升小程序版本更新率。

star的博客 280

保姆级教程:用OpenCV和MediaPipe在Python里实现实时手势识别(附完整代码)

本文提供了一份详细的Python教程,教你如何使用OpenCV和MediaPipe实现实时手势识别系统。从环境配置、手部关键点检测到手势分类算法,逐步讲解如何构建高精度手势识别应用,适用于智能家居控制、PPT操作等场景。教程包含完整代码示例和性能优化技巧,特别适合计算机视觉初学者和开发者实践。

weixin_28677005的博客 327

assert() 函数用法

<br />原文出处:http://dev.firnow.com/course/3_program/c++/cppjs/20071111/85534.html<br />assert宏的原型定义在assert.h中,其作用是如果它的条件返回错误,则终止程序执行. <br />  原型定义: <br />显示代码打印<br />1   #include "assert.h"  <br />2   void assert( int expression ); <br />  assert的作用是现计算表达式 e

ayw_hehe的专栏 792

机器学习实战4-教育领域:学生成绩的可视化分析与成绩预测-详细分析

大家好,我是微学AI,今天给大家带来机器学习实战4-学生成绩的可视化分析与成绩预测,机器学习在教育中的应用具有很大的潜力,特别是在学生成绩的可视化分析与成绩预测方面。机器学习可以通过对学生的父母教育情况和学校表现等数据进行分析和挖掘,从而揭示潜在的学习模式和趋势。

微学AI的博客 7677

C/C++面试笔试知识点总结

C/C++面试问题 1 const关键字的作用? 1)欲阻止一个变量被改变,可使用const,在定义该const变量时,需先初始化,以后就没有机会改变他了; 2)对指针而言,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const; 3)在一个函数声明中,const可以修饰形参表明他是一个输入参数,在函数内部不可以改变其值; 4)对于类的成员函数,有时候必须指定其为const类型,表明其是一个常函数,不能修改类的成员变量; 5)对于类的成员函数,有时候必须指定其返回值为

weixin_42538789的博客 1万+

OpenClaw 在 Docker 容器中的部署实战——零配置启动

本文介绍了OpenClaw在Docker容器中的快速部署方法,对比了本地部署与容器化部署的优势。通过官方镜像和Docker Compose两种方式,5分钟即可完成部署,并详细讲解了配置管理方案(挂载配置文件和环境变量)。文章还提供了飞书集成配置方法,以及生产环境下的日志管理、资源限制、健康检查等优化建议。最后包含常见问题排查指南,帮助开发者快速实现OpenClaw的容器化部署。

刘一说的IT专栏 904

111. 如何创建 SAP ABAP 锁对象(Lock Object)和加锁以及解锁函数

至此,我们完成了 ABAP 系统锁机制和加锁解锁函数的介绍。有了这些基础知识,大家就能在实际工作中,使用 Lock Object 和加锁解锁函数,编写出支持并发访问控制的 ABAP 应用程序了。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1533

【C++】 C++知识点总结

作者:李春港 出处:https://www.cnblogs.com/lcgbk/p/14643010.html 目录前言一、C++常用后缀二、头文件1、C++输入输出2、在C++中使用C的库函数三、指针与动态内存分配1、C2、C++四、命名空间1、作用2、定义3、使用空间成员4、命名空间嵌套5、匿名空间六、引用1、引用特点:2、引用的应用:七、函数重载八、函数缺省参数(默认参数)九、类与对象1、类2、对象十、构造和析构函数1、构造函数<1>构造函数定义及重载<2>构造函数参数列表..

nidongla的博客 935

16、二阶差分功耗分析(DPA)的再审视

本文深入探讨了二阶差分功耗分析(DPA)中的关键问题,包括不同组合函数的性能、信息论分析以及在有轮廓和无轮廓攻击场景下的实验结果。通过对掩码AES和DES的模拟和实际攻击实验,研究了归一化乘积、求和和绝对差值等组合函数在不同噪声水平下的效率,并强调了信息论分析在评估侧信道对抗措施中的重要性。

leaf8的博客 118

后端c++知识点总结

这一篇是C++的一些面试点的总结。 1、一个String类的完整实现必须很快速写出来(注意:赋值构造,operator=是关键)   如果对C++String不熟悉的话,先看http://www.cplusplus.com/reference/去了解一下String类常用的方法,如果想了解C语言的实现,去看一下《C语言接口与实现》(十五章 低级字符串)。   Scott Meyers在《ef

lijun538的专栏 4615

Unreal5从入门到精通之Landscape地形系统

虚幻引擎 5 (UE5) 能够利用其强大的地形编辑工具套件创建大规模的地形世界。使用地形工具可以创建身临其境的户外地形,这些地形经过优化,可在多种不同设备上保持可播放的帧速率。

TxNet 4142

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C++ 知识点总结 面经

C++面试常用知识点总结

Mr_atopos的博客 1210

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【C++】modern-cpp-template - 知识点目录

Modern-cpp-template是一个C++项目模板,它提供了一个 Modern C++ 开发环境。该模板包含了许多实用工具和库,例如CMake构建系统、Doxygen文档生成工具、Google Test测试框架等。通过使用modern-cpp-template,可以快速搭建一个 Modern C++ 项目,而不必从头开始构建整个开发环境。

墨门 160

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

大一下cpp知识点大纲复习

操作符重载允许程序员为类或结构体定义操作符的行为。例如,对于一个表示复数的类Complex,可以通过重载操作符来实现两个复数的加法操作。这样,就可以像操作内置类型(如int或double)一样操作自定义类型。编译时多态(静态多态)通过函数重载和运算符重载实现。在编译时就已经确定调用的具体函数或运算符。运行时多态(动态多态)通过虚函数和虚继承实现。在运行时根据对象的实际类型调用相应的函数。

2401_87275185的博客 1017

C++核心知识点总结

C++核心知识点速查手册

thomaseff的博客 1856

C++ 知识点总结思维导图

C++ 知识点总结思维导图 【下载地址】C知识点总结思维导图 这是一份精心整理的C++知识点总结思维导图,由资深学习者基于自身经验绘制,涵盖C++基本概念、语法结构、面向对象编程、数据结构与算法等核心内容。采用思维导图形式,逻辑清晰,知识点之间的联系一目了然,帮助学习者快速掌握C++精髓。无论是初学者系统学习,还是有一定...

gitblog_06743的博客 464

C++ 散装知识点

不同的cpp文件里的变量和函数可能用的相同的名字,使用命名空间可以避免干扰,防止运行出现bug。1,命名空间的作用。

xxt2020280340111的博客 112
上一篇: C++分级别写日志代码
下一篇: 快速判断一个数是否是2的幂次方,若是,并判断出来是多少次方!
Theodore_Lin
博客等级 码龄16年 24粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值