c++基础问答
c++基础问答
[内容⽹上搜集整理,⾃⼰写⼀部分]
1、评价⼀下C/C++各⾃的特点
答:C语⾔是⼀种结构化语⾔,⾯向过程,基于算法和数据结构,所考虑的是如何通过⼀个过程或者函数从输⼊得到输出;
C++是⾯向对象,基于类、对象和继承,所考虑的是如何构造⼀个对象模型,让这个模型能够契合与之对应的问题,通过获取对象的状态信息得到输出或实现过程控制
2、指针和引⽤的区别
答:(1)指针是⼀个变量,这个变量存储的是⼀个地址,指向⼀块内存;引⽤是变量的⼀个别名。
(2)引⽤定义必须初始化,和⼀个对象绑定,⽽且⼀经绑定,就会⼀直保持和该对象的绑定;指针可以定义不初始化。
(3)赋值⾏为的差异:指针赋值是将指针重新指向另外⼀个对象,⽽引⽤赋值则是修改对象本⾝;
(4)指针之间存在类型转换,⽽引⽤分const引⽤和⾮const引⽤,⾮const引⽤只能和同类型的对象绑定,const引⽤可以绑定到不同但相关类型的对象或者右值
3、数组和指针的区别?
答:1)数组要么在全局数据区被创建,要么在栈上被创建;指针可以随时指向任意类型的内存块;
(2)修改内容上的差别:
char a[]="hello";
a[0]='X';
char*p ="world";// 注意p 指向常量字符串
p[0]='X';//编译器不能发现该错误,运⾏时错误
(3)⽤运算符sizeof 可以计算出数组的容量(字节数)。sizeof§,p 为指针得到的是⼀个指针变量的字节数,⽽不是p
所指的内存容量。C/C++
语⾔没有办法知道指针所指的内存容量,除⾮在申请内存时记住它。注意当数组作为函数的参数进⾏传递时,该数组⾃动退化为同类型的指针
4、空指针和悬垂指针的区别?
答:空指针是指被赋值为NULL的指针;指针指向的内存已经被释放了,但是指针还存在,将会产⽣悬垂指针。
(1) 空指针可以被多次delete,⽽悬垂指针再次删除时程序会变得⾮常不稳定;
(2) 使⽤空指针和悬垂指针都是⾮法的,⽽且有可能造成程序崩溃,如果指针是空指针,尽管同样是崩溃,但和悬垂指针相⽐是⼀种可预料的崩溃。
5、C++中有malloc/free,为什么还有new/delete?
答:malloc/free是C/C++标准库函数,new/delete是C++运算符。他们都可以⽤于动态申请和释放内存。
(1)对于内置类型数据⽽⾔,⼆者没有多⼤区别。malloc申请内存的时候要制定分配内存的字节数,⽽且不会做初始化;new申请的时
候有默认的初始化,同时可以指定初始化;
(2)对于类类型的对象⽽⾔,⽤malloc/free⽆法满⾜要求的。
对象在创建的时候要⾃动执⾏构造函数,销毁之前要调⽤析构函数。由于malloc/free是库函数⽽不是运算符,不在编译器控制之内,不能把执⾏构造函数和析构函数的任务强加给它,因此,C++还需要new/delete。
6、什么是智能指针?
答:当类中有指针成员时,⼀般有两种⽅式来管理指针成员:⼀是采⽤值型的⽅式管理,每个类对象都保留⼀份指针指向的对象的拷贝;另⼀种更优雅的⽅式是使⽤智能指针,从⽽实现指针指向的对象的共享。
  智能指针的⼀种通⽤实现技术是使⽤引⽤计数。智能指针类将⼀个计数器与类指向的对象相关联,引⽤计数跟踪该类有多少个对象共享同⼀指针。
  每次创建类的新对象时,初始化指针并将引⽤计数置为1;当对象作为另⼀对象的副本⽽创建时,拷贝构造函数拷贝指针并增加与之相应的引⽤计数;对⼀个对象进⾏赋值时,赋值操作符减少左操作数所指对象的引⽤计数(如果引⽤计数为减⾄0,则删除对象),并增加右操作数所指对象的引⽤计数;调⽤析构函数时,构造函数减少引⽤计数(如果引⽤计数减⾄0,则删除基础对象)
7、C++函数中值的传递⽅式有哪⼏种?
答:三种传递⽅式为:值传递、指针传递和引⽤传递。
8、对于⼀个频繁使⽤的短⼩函数,在C语⾔中应⽤什么实现,在C++中应⽤什么实现?
答:c⽤宏定义,c++⽤inline
9、内联函数在编译时是否做参数类型检查?
答:内联函数要做参数类型检查, 这是内联函数跟宏相⽐的优势。
10、全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎么知道的?
答:区别:
(1)存储地⽅不同:全局变量存在全局数据区,
局部量存在栈区
(2)⽣命周期不同:
全局变量随主程序创建和创建,随主程序销毁⽽销毁
局部变量在局部函数内部,出栈就不存在;
(3)使⽤⽅式不同:通过声明后全局变量程序的各个部分都可以⽤到;局部变量只能在局部使⽤。
操作系统和编译器通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运⾏的时候被加载。局部变量则分配在堆栈⾥⾯ 。
11、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
答:static全局变量与普通全局变量区别:static全局变量只初使化⼀次,防⽌在其他⽂件单元中被引⽤;
static局部变量和普通局部变量区别:static局部变量放全局静态区,⽣命周期在整个程序运⾏时间,只
被初始化⼀次,下⼀次依据上⼀次结果值;
static函数与普通函数区别:static函数在内存中只有⼀份,普通函数在每个被调⽤中维持⼀份拷贝。
12、程序的局部变量存在于(栈区)中,全局变量存在于(全局/静态区)中,动态申请数据存在于(堆区)中。
13、内联函数在编译时是否做参数类型检查?
答:内联函数要做参数类型检查, 这是内联函数跟宏相⽐的优势。
14、C++⾥⾯是不是所有的动作都是main()引起的?如果不是,请举例.
答:⽐如全局变量的初始化,就不是由main函数引起的
举例:
A a;//a的构造函数限执⾏
int main(){}
15、应⽤程序在运⾏时的内存包括代码区和数据区,其中数据区⼜包括哪些部分?
答:对于⼀个进程的内存空间⽽⾔,可以在逻辑上分成 3个部份:代码区,静态数据区和动态数据区。
动态数据区⼀般就是“堆栈”。 栈是⼀种线性结构,堆是⼀种链式结构。进程的每个线程都有私有的“栈”。
全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。
16、#include<file.h> 与#include "file.h"的区别?
答:尖括号表⽰编译系统根据系统头⽂件存放的⽬录路径去搜索系统头⽂件。
双引号表⽰编译系统⾸先在当前的源⽂件⽬录中查,若未到才根据系统的头⽂件存放的⽬录路径去搜索系统头⽂件
17、头⽂件中的ifndef/define/endif有什么作⽤?
答:主要⽬的是防⽌头⽂件的重复包含和编译。在头⽂件中使⽤#ifndef #define #endif能避免头⽂件的重定义。
18、const 有什么⽤途?
答:在C/C++中,(1)可以定义const常量,(2)修饰函数的返回值和形参;
在C++中,还可以修饰函数的定义体,定义类的const成员函数。被const修饰的东西受到强制保护,可以预防意外的变动,提⾼了程序的健壮性
19、const和#define有什么区别?
答:(1)const和#define都可以定义常量,但是const⽤途更⼴
(2)const 常量有数据类型,⽽宏常量没有数据类型。编译器可以对前者进⾏类型安全检查。⽽对后者只进⾏字符替换,没有类型安全检查,并且在字符替换可能会产⽣意料不到的错误。
(3) 有些集成化的调试⼯具可以对const 常量进⾏调试,但是不能对宏常量进⾏调试。
20、关于sizeof⼩结的。
答:sizeof计算的是在栈中分配的内存⼤⼩。
(1) sizeof不计算static变量占得内存;
(2) 32位系统的指针的⼤⼩是4个字节,64位系统的指针是8字节,⽽不⽤管指针类型;
(3) char型占1个字节,int占4个字节,short int占2个字节
long int占4个字节,float占4字节,double占8字节,string占4字节
⼀个空类占1个字节,单⼀继承的空类占1个字节,虚继承涉及到虚指针所以占4个字节
(4) 数组的长度:
若指定了数组长度,则不看元素个数,总字节数=数组长度*sizeof(元素类型)
若没有指定长度,则按实际元素个数类确定
Ps:若是字符数组,则应考虑末尾的空字符。
(5) 结构体对象的长度
在默认情况下,为⽅便对结构体内元素的访问和管理,当结构体内元素长度⼩于处理器位数的时候,便以结构体内最长的数据元素的长度为对齐单位,即为其整数倍。
若结构体内元素长度⼤于处理器位数则以处理器位数为单位对齐。
(6) unsigned影响的只是最⾼位的意义,数据长度不会改变,所以sizeof(unsigned int)=4
(7) ⾃定义类型的sizeof取值等于它的类型原型取sizeof
(8) 对函数使⽤sizeof,在编译阶段会被函数的返回值的类型代替
(9) sizeof后如果是类型名则必须加括号,如果是变量名可以不加括号,这是因为sizeof是运算符
(10) 当使⽤结构类型或者变量时,sizeof返回实际的⼤⼩。当使⽤静态数组时返回数组的全部⼤⼩,sizeof不能返回动态数组或者外部数组的尺⼨
//sizeof(A) =8
struct A
{
char a;/*剩下3字节补齐*/
int b;/*最⼤类型int,以4字节对齐*/
char c;/*剩下3字节补齐*/
};
//sizeof(B) =16
struct B    //以4个字节对齐
{
char a2;
A a1;/*嵌套的结构体对齐到⾃⼰的最⼤对齐数的整数倍处*/
char b2;
};
//sizeof(C) =12
struct C
{
char a;/*a和b放⼀个对齐⾥,剩下2字节的补齐*/
char b;
int c;/*最⼤类型int,以4字节对齐*/
char d;/*剩下3字节补齐*/
};
//sizeof(D) = 4
struct D
{
int c:16;/*16+14 =30<32所以是4字节*/
int d:14;
};
/
/#pragma pack(n) 可以设置n字节对齐
21、sizeof与strlen的区别?
答: (1)sizeof的返回值类型为size_t(unsigned int);
(2)sizeof是运算符,⽽strlen是函数;
(3)sizeof可以⽤类型做参数,其参数可以是任意类型的或者是变量、函数,⽽strlen只能⽤char*做参数,且必须是以’\0’结尾;
(4)数组作sizeof的参数时不会退化为指针,⽽传递给strlen是就退化为指针;
(5)sizeo是编译时的常量,⽽strlen要到运⾏时才会计算出来,且是字符串中字符的个数⽽不是内存⼤⼩;
22、在C++ 程序中调⽤被C 编译器编译后的函数,为什么要加extern “C”?
答:⾸先,extern是C/C++语⾔中表明函数和全局变量作⽤范围的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使⽤。
通常,在模块的头⽂件中对本模块提供给其它模块引⽤的函数和全局变量以关键字extern声明。
extern "C"是链接申明(linkage declaration)。
被extern"C"修饰的变量和函数是按照C语⾔⽅式编译和链接的。作为⼀种⾯向对象的语⾔,C++⽀持函数重载,⽽过程式语⾔C则不⽀持。函数被C++编译后在符号库中的名字与C语⾔的不同。例如,假设某个函数的原型为:void foo( int x, int y);该函数被C编译器编译后在符号库中的名字为_foo(具体名字编译器决定),⽽C++编译器则会产⽣像_foo_int_int(具体名字编译器决定)之类的名字。
这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。
所以,可以⽤⼀句话概括extern “C”这个声明的真实⽬的:解决名字匹配问题,实现C++与C的混合编程。
23、请描述进程和线程的区别?
答:(1)进程是程序的⼀次执⾏,线程是进程中的执⾏单元;
(2)进程间是独⽴的,这表现在内存空间、上下⽂环境上,线程运⾏在进程中;
(3)⼀般来讲,进程⽆法突破进程边界存取其他进程内的存储空间;⽽同⼀进程所产⽣的线程共享内存空间;
(4)同⼀进程中的两段代码不能同时执⾏,除⾮引⼊多线程。
24、进程间如何通信?
答:管道、命名管道、匿名管道、信号、信号量、消息队列、共享内存、套接字。
25、在⽹络编程中涉及并发服务器,使⽤多进程与多线程的区别?
答:(1)线程执⾏开销⼩,但不利于资源管理和保护;进程则相反,进程可跨越机器迁移。
(2)多进程时每个进程都有⾃⼰的内存空间,⽽多线程间共享内存空间;
(3)线程产⽣的速度快,线程间通信快、切换快;
(4)线程的资源利⽤率⽐较好;
(5)线程使⽤公共变量或者资源时需要同步机制。
26、进程与线程
答:对于有线程系统:进程是资源分配的独⽴单位,线程是资源调度的独⽴单位
对于⽆线程系统:进程是资源调度、分配的独⽴单位。
27、线程之间的同步⽅式
答、(1)锁机制:包括互斥锁/量(mutex)、读写锁(reader-writer lock)、⾃旋锁(spin lock)、条件变量
a、互斥锁/量(mutex):提供了以排他⽅式防⽌数据结构被并发修改的⽅法。
b、读写锁(reader-writer lock):允许多个线程同时读共享数据,⽽对写操作是互斥的。
c、⾃旋锁(spin lock)与互斥锁类似,都是为了保护共享资源。互斥锁是当资源被占⽤,申请者进⼊睡眠状态;⽽⾃旋锁则循环检
测保持着是否已经释放锁。
molloc函数
d、条件变量(condition):可以以原⼦的⽅式阻塞进程,直到某个特定条件为真为⽌。对条件的测试是在互斥锁的保护下进⾏的。
条件变量始终与互斥锁⼀起使⽤。
28、进程之间私有和共享的资源
答:私有:地址空间、堆、全局变量、栈、寄存器
共享:代码段,公共数据,进程⽬录,进程 ID
29、线程之间私有和共享的资源
答:私有:线程栈,寄存器,程序寄存器
共享:堆,地址空间,全局变量,静态变量
30、多进程与多线程间的对⽐、优劣与选择
对⽐维度多进程多线程总结
数据共享、同
步数据共享复杂,需要⽤ IPC;数据是分开的,同步简单
因为共享进程数据,数据共享简单,但也是因为这个原因导致
同步复杂
各有优
内存、CPU占⽤内存多,切换复杂,CPU 利⽤率低占⽤内存少,切换简单,CPU 利⽤率⾼线程占优
创建销毁、切
换创建销毁、切换复杂,速度慢创建销毁、切换简单,速度很快
线程占

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。