c/c++: 面试总结+查漏补缺(一)

2023-05-16

目录

1.C++ 中的类型限定符

2.存储类:static,extern,mutable,thread_local

static 存储类

实例

extern 存储类

实例

实例

mutable 存储类

thread_local 存储类

auto   默认局部变量

注意点:

decltype

3.C++ 引用

C++ 引用 vs 指针

4.c++程序内存

5.局部变量能否和全局变量重名?  

6.全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?   

7.static全局变量与普通的全局变量,static局部变量与普通局部变量有什么区别?static函数与普通函数有什么区别?  

7.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?  

8.Template有什么特点?什么时候用?

9.进程和线程的区别

10.网络编程中设计并发服务器,使用多进程与多线程,请问有什么区别?


1.C++ 中的类型限定符

   类型限定符提供了变量的额外信息。

限定符含义
constconst 类型的对象在程序执行期间不能被修改改变。
volatile修饰符 volatile 告诉编译器不需要优化volatile声明的变量,让程序可以直接从内存中读取变量。对于一般的变量编译器会对变量进行优化,将内存中的变量值放在寄存器中以加快读写效率。
restrict由 restrict 修饰的指针是唯一一种访问它所指向的对象的方式。只有 C99 增加了新的类型限定符 restrict。

 

2.存储类:static,extern,mutable,thread_local

static 存储类

static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。

static 修饰符也可以应用于全局变量。当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。

在 C++ 中,当 static 用在类数据成员上时,会导致仅有一个该成员的副本被类的所有对象共享。

实例

#include <iostream>
 
// 函数声明 
void func(void);
 
static int count = 10; /* 全局变量 */
 
int main()
{
    while(count--)
    {
       func();
    }
    return 0;
}
// 函数定义
void func( void )
{
    static int i = 5; // 局部静态变量
    i++;
    std::cout << "变量 i 为 " << i ;
    std::cout << " , 变量 count 为 " << count << std::endl;
}

当上面的代码被编译和执行时,它会产生下列结果:

变量 i 为 6 , 变量 count 为 9
变量 i 为 7 , 变量 count 为 8
变量 i 为 8 , 变量 count 为 7
变量 i 为 9 , 变量 count 为 6
变量 i 为 10 , 变量 count 为 5
变量 i 为 11 , 变量 count 为 4
变量 i 为 12 , 变量 count 为 3
变量 i 为 13 , 变量 count 为 2
变量 i 为 14 , 变量 count 为 1
变量 i 为 15 , 变量 count 为 0

extern 存储类

extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。当您使用 'extern' 时,对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置。

当您有多个文件且定义了一个可以在其他文件中使用的全局变量或函数时,可以在其他文件中使用 extern 来得到已定义的变量或函数的引用。可以这么理解,extern 是用来在另一个文件中声明一个全局变量或函数。

extern 修饰符通常用于当有两个或多个文件共享相同的全局变量或函数的时候,如下所示:

第一个文件:main.cpp

实例

#include <iostream>
 
int count ;
extern void write_extern();
 
int main()
{
   count = 5;
   write_extern();
}

第二个文件:support.cpp

实例

#include <iostream>
 
extern int count;
 
void write_extern(void)
{
   std::cout << "Count is " << count << std::endl;
}

在这里,第二个文件中的 extern 关键字用于声明已经在第一个文件 main.cpp 中定义的 count。现在 ,编译这两个文件,如下所示:

$ g++ main.cpp support.cpp -o write

这会产生 write 可执行程序,尝试执行 write,它会产生下列结果:

$ ./write
Count is 5

mutable 存储类

mutable 说明符仅适用于类的对象,。它允许对象的成员替代常量。也就是说,mutable 成员可以通过 const 成员函数修改。

thread_local 存储类

使用 thread_local 说明符声明的变量仅可在它在其上创建的线程上访问。 变量在创建线程时创建,并在销毁线程时销毁。 每个线程都有其自己的变量副本。

thread_local 说明符可以与 static 或 extern 合并。

可以将 thread_local 仅应用于数据声明和定义,thread_local 不能用于函数声明或定义。

以下演示了可以被声明为 thread_local 的变量:

thread_local int x;  // 命名空间下的全局变量
class X
{
    static thread_local std::string s; // 类的static成员变量
};
static thread_local std::string X::s;  // X::s 是需要定义的
 
void foo()
{
    thread_local std::vector<int> v;  // 本地变量
}

auto   默认局部变量

C++11中引入auto第一种作用是为了自动类型推导

auto的自动类型推导,用于从初始化表达式中推断出变量的数据类型。通过auto的自动类型推导,可以大大简化我们的编程工作

auto实际上实在编译时对变量进行了类型推导,所以不会对程序的运行效率造成不良影响

另外,似乎auto并不会影响编译速度,因为编译时本来也要右侧推导然后判断与左侧是否匹配

auto a; // 错误,auto是通过初始化表达式进行类型推导,如果没有初始化表达式,就无法确定a的类型  

auto i = 1;  

auto d = 1.0;

 

 auto的作用就是为了简化变量初始化,如果这个变量有一个很长很长的初始化类型,就可以用auto代替。

注意点:

1.用auto声明的变量必须初始化(auto是根据后面的值来推测这个变量的类型,如果后面没有值,自然会报错)

2.函数和模板参数不能被声明为auto(原因同上)

3.因为auto是一个占位符,并不是一个他自己的类型,因此不能用于类型转换或其他一些操作,如sizeof和typeid

4.定义在一个auto序列的变量必须始终推导成同一类型
 

decltype

decltype实际上有点像auto的反函数,auto可以让你声明一个变量,而decltype则可以从一个变量或表达式中得到类型,有实例如下:

  1. int x = 3;  
  2. decltype(x) y = x; 

 

3.C++ 引用

引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。

C++ 引用 vs 指针

引用很容易与指针混淆,它们之间有三个主要的不同:

  • 不存在空引用。引用必须连接到一块合法的内存。
  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
  • 引用必须在创建时被初始化。指针可以在任何时间被初始化。

4.c++程序内存

通常有以下四个区:

全局数据区:全局变量,静态变量,字符串常量,常变量

代码区:所有函数和代码

栈区:为运行函数而分配的函数参数,局部变量,返回地址

堆区:动态内存分配

5.局部变量能否和全局变量重名?  

 答:能,局部会屏蔽全局。要用全局变量,需要使用"::" ;局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。

全局变量的生命周期是整个程序运行的时间,而局部变量的生命周期则是局部函数或过程调用的时间段。其实现是由编译器在编译时采用不同内存分配方法。

全局变量在main函数调用后,就开始分配,

静态变量则是在main函数前就已经初始化了。

局部变量则是在用户栈中动态分配的(还是建议看编译原理中的活动记录这一块)

6.全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?   

答:可以,在不同的C文件中以static形式来声明同名全局变量。   可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错.  

 

7.static全局变量与普通的全局变量,static局部变量与普通局部变量有什么区别?static函数与普通函数有什么区别?  

1)同:static全局变量与普通全局变量在存储方式上没有什么区别,都是在全局数据区上以静态方式存储;

     异:普通全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。

2)) 从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。                   

 3) static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件   

综上所述:

static全局变量与普通的全局变量有什么区别:

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

static局部变量和普通局部变量有什么区别:

static局部变量只被初始化一次,下一次依据上一次结果值;   

static函数与普通函数有什么区别:

static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

7.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?  

 c用宏定义,c++用inline  

8.Template有什么特点?什么时候用?

  答: Template可以独立于任何特定的类型编写代码,是泛型编程的基础.

     当我们编写的类和函数能够多态的用于跨越编译时不相关的类型时,用Template.

     模板主要用于STL中的容器,算法,迭代器等以及模板元编程.

(C++的template是实现在库设计和嵌入式设计中的关键。
template能实现抽象和效率的结合;同时template还能有效地防止代码膨胀)

9.进程和线程的区别

进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。

线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。

一个程序至少一个进程,一个进程至少一个线程。

10.网络编程中设计并发服务器,使用多进程与多线程,请问有什么区别?

1)进程:子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。

2)线程:相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

两者都可以提高程序的并发度,提高程序运行效率和响应时间。

      线程和进程在使用上各有优缺点:

线程执行开销小,但不利于资源管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

对资源的管理和保护要求高,不限制开销和效率时,使用多进程。

要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程。

参考来源:1.C语言面试题大汇总之华为面试题

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c/c++: 面试总结+查漏补缺(一) 的相关文章

  • SQL面试总结

    一 查询性能优化 1 使用 Explain 进行分析 Explain 用来分析 SELECT 查询语句 xff0c 开发人员可以通过分析 Explain 结果来优化查询语句 比较重要的字段有 xff1a select type 查询类型 x
  • C 中strcpy和memcpy的区别

    参考博客 https blog csdn net zcyzsy article details 53190691 https www cnblogs com metootxy p 3185000 html 一 以下是具体使用memcpy这个
  • URL地址的两种格式

    1 传统格式 格式 scheme host port path query fragment scheme 协议 例如http https ftp等 必写 host 域名或IP地址 必写 port 端口号 http 默认端口为 80 可以省
  • 最新golang语言面试题总结(一)

    1 go中make和new区别 new 分配内存 内存里存的值是对应类型的零值 只有一个参数 参数是分配的内存空间所存储的变量类型 Go语言里的任何类型都可以是new的参数 比如int 数组 结构体 甚至函数类型都可以 返回的是指针 mak
  • C++面试总结(一)

    参考博客 C C 面试知识总结 blackwall 博客园 C 面试题目 整理自牛客网 四轩茶屋 CSDN博客 c 牛客网 1 sizeof和strlen的区别 sizeof是运算符 计算数据所占的内存空间 strlen 是一个函数 计算字
  • MySQL主从同步原理

    主从复制 是用来建立一个和主数据库完全一样的数据库环境 称为从数据库 主数据库一般是准实时的业务数据库 原理 数据库有个bin log二进制文件 记录了所有sql语句 我们的目标就是把主数据库的bin log文件的sql语句复制过来 让其在
  • Vue组件常用的六种通信方式

    Vue js 组件实例的作用域是相互独立的 不同组件之间的数据不能互相访问 组件有父级组件 子级组件 兄弟组件 如何选择组件之间的通信方式 针对常用的 props emit on vuex parent children attrs lis
  • 2019/8/13面试内容

    1 基本数据类型 5种 boolean string number undefined object 对象 null 2 闭包原理 优缺点 3 变量回收机制 4 如何判断ie浏览器 5 有没有尝试自己封装ajax 写出原生ajax 6 re
  • Spring Boot多线程环境下,解决多个定时任务冲突问题

    问题引入 关于定时任务注解 Scheduled在之前的文章已经讲到 Spring Boot定时器默认的是单线程的 但是问题就来了 如果在线程争夺资源后 某个线程需要比较长时间才能执行完 那其他的定时器怎么办 都只能进入等待状态 时间越久 累
  • C++面试之const和static的联系和区别

    C 中的静态成员和静态函数的参考之前写的博客 C 中的静态成员和静态函数 Littlehero 121的博客 CSDN博客 C 中的全局变量和普通全局变量参考之前写的博客 全局变量 静态全局变量 静态局部变量和普通局部变量的区别 Littl
  • C/C++中的头文件加上头文件中的ifndef/define/endif有什么作用?

    参考博客 https blog csdn net summer00072 article details 80883514 主要的作用就是防止头文件重复包含了 这个作用在Qt中是已经给你做好了 qt新建一个文件的时候就会直接给你建立完毕
  • Spring bean的生命周期

    对于普通的Java对象 当new的时候创建对象 当它没有任何引用的时候被垃圾回收机制回收 而由Spring IoC容器托管的对象 它们的生命周期完全由容器控制 bean的声明 bean的声明有好几种 如上图 上图声明的一些bean信息可以通
  • 面试总结(1)---7.28

    Ajax关于readyState 状态值 和status 状态码 的研究 var getXmlHttpRequest function try 主流浏览器提供了XMLHttpRequest对象 return new XMLHttpReque
  • 我的春招实习+秋招总结【前端开发】

    双非本科 通信工程 算是转到IT行业这边的了 从大二暑期正式开始学习前端 想想已经一年的时间了 期间经历了很多 从迷惘到清晰 从艰难自学到找到实习 从备战秋招到找到工作 能经历的我都经历过了 来说说那些 前端工作者 的艰辛与欢乐 开始自学前
  • 【面试系列】JDK动态代理和CGLIB静态代理

    文章目录 前言 JDK动态代理代码实例 Cglib 代理代码实例 两者优缺点 前言 是否在面试过程中经常被问到Spring的代理的问题 比如说几种代理方式 两种代理方式的区别 或者问为什么JDK动态代理只能代理接口 如果你能回答出来JDK动
  • OOM(内存溢出)造成原因及解决方案

    一 概念 内存溢出 Out Of Memory 简称OOM 是指应用系统中存在无法回收的内存或使用的内存过多 最终使得程序运行要用到的内存大于能提供的最大内存 二 造成原因 2 1 内存泄漏 由于长期保持某些资源的引用 垃圾回收器无法回收它
  • Java无法通过形参设置为null改变实参

    文章目录 问题描述 问题例子 问题分析 问题描述 在实际业务开发过程中 我们会把实参传递给形参 在方法体内对引用对象进行构建或者修改 从而改变实参 因为对形参对象属性修改时 实参对象也会随着改变 详情请看 Java是值传递还是引用传递 区别
  • 面试总结(七):大数据与高并发-1

    问题导读 1 秒杀系统的架构设计是怎样的 2 为什么要使用NOSQL NOT ONLY SQL 3 传统RDBMS和NOSQL的区别是什么 大数据与高并发一 秒杀架构设计业务介绍什么是秒杀 通俗一点讲就是网络商家为促销等目的组织的网上限时抢
  • 小记-面试时对MVC的理解

    MVC分别表示模型 视图 控制 1 模型层也叫业务逻辑层 是整个应用程序的核心 模型层接收视图层请求的数据并处理 返回最终的结果 2 视图层就是用户看到的并与之交互的界面 3 控制层就是接收用户的请求 并根据请求来决定调用哪个模型和视图去完
  • 第一次面试前端实习生心得

    今天第一次去面试前端岗位的实习生 公司规模不算大吧 不过也有好几个部门 说说我的面试心得吧 首先是hr面 如下是她问的问题 学这个多久了 大四还有没有课 是否只需完成毕业设计就行了不用上课 同学暑假都在干嘛 学校课程学了什么 同学们主要找哪

随机推荐