C/C++知识点

1 指针和引用的区别

①指针是一个变量,这个变量里存放一个地址,指向内存的一个存储单元,引用只是一个变量的别名;

②指针可以为NULL,引用不可为空必须初始化;

③指针的值初始化之后可以改变,引用初始化之后不可以改变;

④可以有多级指针不可以有多级引用;

⑤sizeof指针,得到指针本身自己的大小,32位系统是4,64位系统是8,sizeof引用,得到指向对象的大小。

2 静态变量和普通变量的区别

①static全局变量只初始化一次,防止其他文件单元被引用;

②static局部变量只初始化一次,下一次依据上一次的结果值;而普通变量在下一次调用时还是用初始化的值;

③static函数在内存中只有一份,普通函数在每一次被调用中维持一份复制品。

4 阻塞和非阻塞

是把数据从用户空间拷贝到内核空间缓冲区这段时间而言的。

⑴如果发送缓冲区剩余空间> 想要发送data字节数

阻塞非阻塞都会将数据拷贝到内核,并且大小就是想要发送数据的大小;

⑵如果发送缓冲区剩余空间< 想要发送data字节数

  ①阻塞模式

会阻塞,等到内核缓冲区有足够的空闲空间,再继续将数据拷贝到内核,直到拷贝完,返回值就是发送数据的数据量;

②非阻塞模式

  当内核缓冲区被填满后立即返回,返回值是已经拷贝到发送缓冲区的数据量。

5 static关键字的作用

  ⑴在面向过程的编程中

①隐藏。在变量或者函数前加上static,只是对本文件可见,对其他文件不可见。

②只初始化一次,并且默认初始化为0

③如果作为static局部变量在函数内定义,它的生存期为整个源程序,但是其作用域是定义该变量的函数,只能在定义该变量的函数内使用该变量。退出该函数后,尽管该变量还继续存在,但不能使用它。

⑵面向对象的编程

①类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,仅能访问类的静态数据和静态成员函数。     

②不能将静态成员函数定义为虚函数。      

③在类中定义static相当于一个全局变量,但是一定在类外进行初始化,

int son::num=222;

④在不声明类对象就能使用类中的变量和函数,只需要在前面加上作用域就可以;

6 const作用

   可以定义const常量,如const int Max = 100;

  便于进行类型检查,保护被修饰的东西,防止意外的修改,如

   void f(const int i){...}编译器就会知道i是一个常量,不允许修改

  const定义的常量在程序运行过程中只有一份拷贝,

   修饰指针

const int *A; //const修饰指向的对象,A可变,A指向的对象不可变

int *const A; //const修饰指针A,A不可变,A指向的对象可变

const int *constA; //指针A和A指向的对象都不可变

  修饰引用

const double &A; //该引用所引用的对象不能被更新

  修饰函数的返回值

是返回值不可被改变,格式如下:constint Fun1();

  修饰类的成员变量

   int Fun() const;这样,函数Fun中不能修改类里面的数据。

  在另一连接文件中引用const常量

extern const inti;   //正确的引用

extern const int j =10;//错误,常量不可以被再次赋值

⑨提高了效率

  编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

7  斐波那契数列求时间复杂度

  例T(n) = 2T(n/2)+1,其时间复杂度是O(n);

  公式:T(n) = aT(n/b)+f(n); a递归调用次数

                             b数据规模

                             f(n)单次过程的时间复杂度

  比较 和f(n) ① > f(n) 时间复杂度是:O()

                   ② < f(n)              O()

8 break   :跳出当前循环或者switch语句

  Continue:结束当前循环,开始下一轮循环

9、斐波那契数列求第n项

  注意只要用到后一项等于几的情况都要考虑斐波那契数列。

  ①下一项等于前两项的和

  ②下一项等于前(n-1)项的和

10、结构与联合有和区别?

(1). 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在(不同成员的存放地址不同)。 

(2). 对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。

11、main 函数执行以前,还会执行什么代码?

答案:全局对象的构造函数会在main 函数之前执行。

 

12.分别写出BOOL,int,float,指针类型的变量a 与“零”的比较语句。

BOOL : if ( !a ) or if(a)

Int   : if ( a == 0)

float : const EXPRESSION EXP = 0.000001

if ( a < EXP && a >-EXP)

pointer : if ( a != NULL) or if(a == NULL)

13.const与 #define 的比较,const有什么优点?

(1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应)。

(2)  有些集成化的调试工具可以对 const 常量进行调试,但是不能对宏常量进行调试。

14.全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?

①生命周期不同:

全局变量随主程序创建而创建,随主程序销毁而销毁;

局部变量在局部函数内部,甚至局部循环体等内部存在,退出就不存在;

②使用方式不同:

通过声明后全局变量程序的各个部分都可以用到;

局部变量只能在局部使用;分配在栈区。 

操作系统和编译器通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运行的时候被加载。局部变量则分配在堆栈里面。

15. 什么时候需要“引用”?

流操作符<<和>>、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。 
以上 2-8 参考:http://blog.csdn.net/wfwd/archive/2006/05/30/763551.aspx 

16. extern “C”

在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?

⑴extern是C/C++语言中表明函数和全局变量作用范围的关键字,该关键字告诉编译器,  其声明的函数和变量可以在本模块或其它模块中使用。 

⑵使用的时候,是在模块的头文件中,对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。

例如,如果模块B欲引用该模块A中定义的全局变量和函数时,需要在A的头文件中把B想要引用的A的全局变量和函数前面加上extern,而B在使用的时候只需包含模块A的头文件即可。

⑶extern "C"用于C++要使用C的变量和函数的时候,是连接申明,被extern "C"修饰的变量和函数是按照C语言方式编译和连接的。

C++支持函数重载,而过程式语言C则不支持。

例如,假设某个函数的原型为: voidfoo( int x, int y ); 
  该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。

例如,在C++中,函数void foo( int x,int y )与void foo( int x,float y )编译生成的符号是不相同的,后者为_foo_int_float。 

 实现C++与C及其它语言的混合编程。   
明白了C++中extern"C"的设立动机,我们下面来具体分析extern "C"通常的使用技巧: 
extern "C"的惯用法 
(1)在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理: 
extern "C" 

#i nclude"cExample.h" 

而在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern"C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。 
C++引用C函数例子工程中包含的三个文件的源代码如下: 
/* c语言头文件:cExample.h */ 
#ifndef C_EXAMPLE_H 
#define C_EXAMPLE_H 
extern int add(int x,int y); 
#endif 
/* c语言实现文件:cExample.c */ 
#i nclude"cExample.h" 
int add( int x, int y ) 

return x + y; 

// c++实现文件,调用add:cppFile.cpp 
extern "C" 

#i nclude"cExample.h" 

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

add(2,3); 
return 0; 

如果C++调用一个C语言编写的.DLL时,当包括.DLL的头文件或声明接口函数时,应加extern"C" { }。 
(2)在C中引用C++语言中的函数和变量时,C++的头文件需添加extern"C",但是在C语言中不能直接引用声明了extern "C"的该头文件,应该仅将C文件中将C++中定义的extern "C"函数声明为extern类型。 
C引用C++函数例子工程中包含的三个文件的源代码如下: 
//C++头文件 cppExample.h 
#ifndef CPP_EXAMPLE_H 
#define CPP_EXAMPLE_H 
extern "C" int add( int x, int y ); 
#endif 
//C++实现文件 cppExample.cpp 
#i nclude"cppExample.h" 
int add( int x, int y ) 

return x + y; 

/* C实现文件 cFile.c 
/* 这样会编译出错:#i nclude "cExample.h" */ 
extern int add( int x, int y ); 
int main( int argc, char* argv[] ) 

add( 2, 3 ); 
return 0; 

17 面向对象和面向过程的区别?

   面向对象的三个特点是封装,继承和多态。

  ①封装性上

面向对象的封装:将一系列的数据和方法封装在类中;

面向过程的封装:数据用struct封装,方法不封装,方法和数据是分离的。

  ②代码复用上

面向对象:利用继承的方式服用;

面向过程:只能以普通的函数复用。

18  map,set的底层实现?

     Map和set都是STL中的关联容器,内部采用的就是一种非常高效的平衡检索二叉树:红黑树来实现的;

      Map内部自建一颗红黑树,这棵树具有对数据自动排序的功能,所以map内部所有的数据都是有序的;一个map是一键值对序列,

      红黑树是结合了链表添加删除方便;和数组查找效率高的优点,所以map应用起来方便高效。

19  map,set的区别?

vector封装数组,list封装了链表,mapset封装了二叉树等

          ①Map和set都是属于STL中的关联容器,

MAP的节点是一对数据.;使用关键值Key来唯一标识每一个成员 map可以重复;

SET的节点是一个数据,set是一个集合                                    
  
只不过,map的形式  map<type1,   type2>   mymap;   
             set
的形式  set<type>   myset;  

map是映射集合中的元素不能重复,set可以进行集合的各种操作(交并补等),当然set一般是用平衡树或哈西表实现的。

List特点:元素有放入顺序,元素可重复 
Map特点:元素按键值对存储,无放入顺序 
Set特点:元素无放入顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在  set中的位置是有该元素的HashCode决定的,其位置其实是固定的)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值