delete与new配套,delete []与new []配套。

4.在物理内存为1G的计算机中能否malloc(1.2G)?

在支持虚拟内存管理的操作系统上:当请求的内存大于128kb,malloc()会调用mmap()分配一起分配内存。

在不支持虚拟内存管理的实时操作系统上运行:这种情况下,在只有1G物理内存的计算机上malloc(1.2G)就会失败。

5.用C写个程序,如何判断一个操作系统是16位还是32位的?

定义一个指针p,打印出sizeof( p ),如果节后是4,则表示该操作系统是32位,打印结果是2,表示是16位。

6.解释下位域,为什么要用位域,位域的好处?

在计算机中,有些信息存储时并不需要占用一个完整的字节,而只需占用一个或几个二进制位。比如在存放一个只有0和1两种状态的开关量时,

用一位二进制位即可表示。因此,为了节省存储空间,C语言提供了一种称为“位域”的数据结构来充分利用存储空间。

7.位操作

位与符号是一个&,两个&&是逻辑与,位或符号是一个|,两个||是逻辑或。

C语言中按位取反是~,C语言中的逻辑取反是!。

左移位<<与右移位>>

对于无符号数,左移时右侧补0(相当于逻辑移位),右移时左侧补0(相当于逻辑移位)
对于有符号数,左移时右侧补0(叫算术移位,相当于逻辑移位),右移时左侧补符号位(如果正数就补0,负数就补1,叫算术移位)
嵌入式中研究的移位,以及使用的移位都是无符号数.

https://blog.csdn.net/weixin_49303682/article/details/118662325

8.在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。

int *p;
p = (int *)0x67a9;
*p = 0xaa66;

9.给定一个整型变量a,写两段代码,第一个设置a的bit3,第二个清除a的bit,在以上两个操作中,要保持其它位不变。

 #define BIT3 (0x1<<3)
 static int a;
 void set_bit3(void)
 {
  a |= BIT3;
 }
 void clear_bit3(void)
 {
  a &= ~BIT3;
 }

10.什么是右值引用,跟左值又有什么区别

左值:能对表达式取地址,一般指表达式结束后依然存在的持久对象。

右值:不能对表达式取地址,一般表达式结束后就不再存在的临时对象。

11.判断x=x+1,x+=1,x++哪个效率最高?为什么?

x++的效率最高,直接去出来+1后在放回原来的地址。

x=x+1最低, 因为执行步骤如下:  <1>读取右x的地址;  <2>x+1;  <3>读取左x的地址,<4>将右值传给左边的x(编译器并不认为左右两边的x的地址相同)。

12.用变量a定义

一个整型数   int a;
 一个指向整型数的指针  int *a;
 一个指向指针的指针,它指向的指针式指向一个整型数  int **a;
 一个有10个整型数的数组   int a[10];
 一个有10指针的数组,该指针是指向一个整型数  int *a[10];
 一个指向有10个整型数数组的指针   int (*a)[10];
 一个指向函数的指针,该函数有一个整型数参数并返回一个整型数   int (*a)(int);
 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型数参数并返回一个整型  int (*a[10])(int);

13.C语言是强类型的语言,这是什么意思?

C语言是一种强类型的程序设计语言,int x,y,z;在C程序中,每一个变量都必须声明其取值类型。

char 占8位1字节,short占16位2字节,int 占32位4字节,long 占32位4字节,float占32位4字节,double占64位8字节。

14.char 与 int之间的转换

从长字节数据类型转换为短字节数据类型,会产生截断:从4字节的int类型转换成1个字节的char类型,则取int数据的最低的一个字节。

从短字节类型转换为长字节类型:从char转换为int:则在前面的三个字节补符号位0x000000。

15.float(单精度浮点型)和double(双精度浮点型)

float:1bit(符号位)+8bit(指数位)+23(尾数位) 2^23=8388608,共7位,意味着最多有7位有效数字。

double:1bit(符号位)+11bit(指数位)+52bit(尾数位) 2^52=4503599627370496. 一共16位,同理double的精度为15~16位。

 #include <stdio.h>
 int main(void)
 {
     float m = (float)3.14;
     double n = 10.5;
     printf("%f,%lf\n",m,n);
     return 0;
 }

输出:3.140000,10.500000 因为%lf只保留小数点后6位。

16.字符常量

char beta; beta=’ab’; 是错误的,改正:char beta; beta=’ab/’

char beta; beta=”a”; 是错误的,改正:char beta; beta=’a’

定义字符串数组:char a[ ] = “abcse”

非图形字符,如退格,换行,也可以表示成字符型常量。表示方法是使用转义字符”/”;

已知char b[5],*p=b; ,则正确的赋值语句是  C

A. b=“abcd” ; B. *b=“abcd”; C. p=“abcd”; D. *p=“abcd”;

下列可以正确表示字符型常量的是  D

A、297 B、“a” C、“\n” D、‘\t’

17.写出bool 、int、 指针变量与“零值”比较的if语句

bool型数据:

if( flag ) {  A; } else {  B; }

int型数据:

if( 0 != flag ) {  A; } else {  B; }

指针型数:

if( NULL == flag ) {  A; } else {  B; }

18.写出float x 与“零值”比较的if语句。

if(x>0.000001&&x<-0.000001)

19.区分 %d,  %ld,  %lld,  %lf,  %f

%d=int,

%ld=long,

%lld=long long;

在32位编译器上,int=long=32bit;long long=64bit。

输入时:

float 输入用 %f,小数点后6位。

double 输入用 %lf,小数点后6位。

20.输出数据问题

printf(“%d\n”,101010);  默认的方式是左对齐。

printf(“%-10d\n”,101010); 在打印数字宽度前面加一个“-”也是左对齐,10表示数字宽度为10,其他空格补齐。

printf(“%10d”,101010); 在%和d之间加上数字宽度,就可以右对齐了,10表示数字宽度为10,其他空格补齐。

 double a = 326.3845;
 printf("%10.3f\n", a);
 结果是:
    326.385(注意前面是有空格的)
 printf("%04d", 3);
 结果为:
 0003

21.嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环

 while(1)
 {
 ;}
 for(;;)
 {
 ;}

22.惰性计算方法

 #include "stdio.h"
 void main()
 {
     int n = 2, k = 0;
     while(k++&&n++>2);
     printf("%d %d\n",k,n);
 }
 输出的正确答案是1  2

刚开始运算的时候,k的值是0,n的值是2,并还没有进行自增1的操作,自增1要在下一次循环中。对于循环条件(k++&&n++>2),

首先计算k,由于k的初值为0,k++是后坐,因此k++在参与比较的时候是0(假),比较以后k值增1(变为1),这时,系统不会再计算&&后面的表达式了(即

所谓的惰性计算方法),所以,n++>2没有参与运算,也就是说,循环语句执行之后,k的值是1,n的值是2.

23.变量的声明和定义有什么区别

为变量分配地址和存储空间的称为定义,不分配地址的称为声明。一个变量可以在多个地方声明,但是只在一个地方定义。

加入extern修饰的是变量的声明,说明此变量将在文件以外或在文件后面部分定义。

24.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)

#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL

25.写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个

#define MIN(a, b) (a) <= (b) ? (a) : (b)

26.sizeof和strlen的区别

sizeof的参数可以是数据的类型,也可以是变量,而strlen只能以结尾为‘\0‘的字符串作参数。

sizeof计算的是数据类型占内存的大小,而strlen计算的是字符串实际的长度。

27.c语言中的static和C++中static的区别

static在C语言中具有:记忆性,隐藏性,初始化为0的特点。

而C++中除了上述功能外,还用来定义类的成员变量和函数。即静态成员和静态成员函数。

28.C++函数中值的传递方式有哪几种?

C++函数的三种传递方式为:值传递、指针传递和引用传递。

29.C++里面是不是所有的动作都是main()引起的?如果不是,请举例。

比如全局变量的初始化,就不是由main函数引起的。举例:

 class   A{}; 
 A   a;          //a的构造函数限执行   
 int   main() {}  

30.谈谈对面向对象的认识

面向对象可以理解成对待每一个问题,都是首先要确定这个问题由几个部分组成,而每一个部分其实就是一个对象。

然后再分别设计这些对象,最后得到整个程序。传统的程序设计多是基于功能的思想来进行考虑和设计的,而面向对象的

程序设计则是基于对象的角度来考虑问题。这样做能够使得程序更加的简洁清晰

31.谈谈你对编程规范的理解

编程规范可总结为:程序的可行性,可读性、可移植性以及可测试性。

说明:这是编程规范的总纲目,面试者不一定要去背诵上面给出的那几个例子,应该去理解这几个例子说明的问题,

想一想,自己如何解决可行性、可读性、可移植性以及可测试性这几个问题,结合以上几个例子和自己平时的编程习惯来回答这个问题。

32.面向对象的三大特性

面向对象的三大特征是封装性、继承性和多态性:

封装性:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private, protected,public)。

继承:继承主要实现重用代码,节省开发时间,子类可以继承父类的属性和方法。

多态性:是将父类对象设置成为和一个或更多它的子对象相等的技术。用子类对象给父类对象赋值之后,父类对象就

可以根据当前赋值给它的子对象的特性以不同的方式运作。

33.简述多态的原理

编译器发现一个类中有虚函数,便会立即为此类生成虚函数表 vtable。虚函数表的各表项为指向对应虚函数的指针。

编译器还会在此类中隐含插入一个指针vptr(对vc编译器来说,它插在类的第一个位置上)指向虚函数表。调用此类的构造函数时,

在类的构造函数中,编译器会隐含执行vptr与vtable的关联代码,将vptr指向对应的vtable,将类与此类的vtable联系了起来。

另外在调用类的构造函数时,指向基础类的指针此时已经变成指向具体的类的this指针,这样依靠此this指针即可得到正确的vtable,。

如此才能真正与函数体进行连接,这就是动态联编,实现多态的基本原理。

34.多态的作用?

主要是两个:(1)隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;

(2)接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。

35.多态,虚函数,纯虚函数

多态:是对于不同对象接收相同消息时产生不同的动作。

虚函数:在基类中冠以关键字 virtual 的成员函数。 它提供了一种接口界面。允许在派生类中对基类的虚函数重新定义。

纯虚函数的作用:在基类中为其派生类保留一个函数的名字,以便派生类根据需要对它进行定义。作为接口而存在,纯虚函数不具备函数的功能,一般不能直接被调用。

具有纯虚函数的类是抽象类(abstract class),不能声明对象,只能作为基类为派生类服务,除非派生类完全实现了基类的所有纯虚函数,否则派生类也成为抽象类,不能

声明对象。

36.重载(overload)、重写(override,有的书也叫做“覆盖”)、重定义(redefinition)的区别?

重载 同一名字子空间 是指允许存在多个同名函数,而这些函数的参数表不同。
重定义/隐藏 不同名字子空间 用于继承,派生类与基类的函数同名,屏蔽基类的函数
重写/覆盖 不同名字子空间 用于继承,子类重新定义父类虚函数的方法

37.所有的运算符都能重载吗?

不能被重载的运算符

在 C++运算符集合中,有一些运算符是不允许被重载的。这种限制是出于安全方面的考虑,可防止错误和混乱。

(1)不能改变 C++内部数据类型(如 int,float 等)的运算符。

(2)不能重载‘.’,因为‘.’在类中对任何成员都有意义,已经成为标准用法。

(3)不能重载目前 C++运算符集合中没有的符号,如#,@,$等。原因有两点,一是难以理解,二是难以确定优先级。

(4)对已经存在的运算符进行重载时,不能改变优先级规则,否则将引起混乱。

38.用C++设计一个不能继承的类

 template <typename T> 
 
 class A 
 {  
    friend T; 
  private:  
    A() {}  
     ~A() {} 
  };  
 
 class B : virtual public A<B> 
 { 
 public:  
    B() {}  
    ~B() {} 
 }; 
 
 void main( void ) 
 {  
     B b;  
     return; 
} 

39.构造函数能否为虚函数

构造函数不可以,析构函数可以。

因为对象中的虚函数表指针是在构造函数初始化列表阶段才初始化的。

如果它的构造函数是虚函数,那就要通过对象中的虚函数表指针来调用,而这个虚函数表是在构造函数初始化列表阶段才初始化的。

https://blog.csdn.net/qq_41830537/article/details/102626648

**40.在C中用const 能定义真正意义上的常量吗?C++中的const呢?

*const修饰的变量是只读的,本质上还是变量,与C语言不同,c++中的const不是只读变量。*C++中的const是个真正意义上的常量。

C语言中的const还是可变的:

 int main()
 {
      const int c = 0;
     int* p = (int*)&c;  
      printf("Begin...\n"); 
      *p = 5;
     printf("c = %d\n", c);  //C语言编译:输出5,
                                       //说明c并不是真正意义上的常量 
      return 0;
 }

由于c++中const常量的值在编译期就已经决定,下面的做法是OK的,但是c中是编译通不过的。

int main(void)
 {
     const int a = 8;
     const int b = 2;
     int array[a+b] = {0};
     return 0;
}

41.宏和内联(inline)函数的比较?

(1)内联(inline)函数是C++中引用的一个新的关键字;C++中推荐使用内联函数来替代宏代码片段;

(2)内联函数将函数体直接扩展到调用内联函数的地方,这样减少了参数压栈,跳转,返回等过程;

(3)  由于内联发生在编译阶段,所以内联相较宏,是有参数检查和返回值检查的,因此使用起来更为安全;

(4)内联函数不能过于复杂,最初C++限定不能有任何形式的循环,不能有过多的条件判断,不能对函数进行取地址操作等,

但是现在的编译器几乎没有什么限制,基本都可以实现内联。

42.typedef和define由什么区别

用法不同:typedef用来定义一种数据类型的别名,增强程序的可读性。define主要用来定义常量,以及书写复杂使用频繁的宏。

执行时间不同:typedef是编译过程的一部分,有类型检查的功能。define是宏定义,是预编译的部分,其发生在编译之前,只是简单的进行字符串的替换,不进行类型的检查。

https://blog.csdn.net/qq_45607873/article/details/123746610

**43.strcat、strncat、strcpy哪些函数会导致内存溢出?如何改进?

strcpy函数会导致内存溢出。

strcpy拷贝函数不安全,他不做任何的检查措施,也不判断拷贝大小,不判断目的地址内存是否够用。

char *strcpy(char *strDest,const char *strSrc)

strncat()主要功能是在字符串的结尾追加n个字符。

char * strncat(char *dest, const char *src, size_t n);

strcat()函数主要用来将两个char类型连接。例如:

char d[20]="Golden"; 
char s[20]="View"; 
strcat(d,s); //打印d printf("%s",d);

输出 d 为 GoldenView (中间无空格)

**延伸**

memcpy拷贝函数,它与strcpy的区别就是memcpy可以拷贝任意类型的数据,strcpy只能拷贝字符串类型。

memcpy 函数用于把资源内存(src所指向的内存区域)拷贝到目标内存(dest所指向的内存区域);

有一个size变量控制拷贝的字节数;

函数原型:

void *memcpy(void *dest, void *src, unsigned int count);

44.简述队列和栈的异同

队列和栈都是线性存储结构,但是两者的插入和删除数据的操作不同,队列是“先进先出”,栈是“后进先出”。

45.堆和栈的区别?

堆存放动态分配的对象——即那些在程序运行时动态分配的对象,比如 malloc出来的对象,其生存期由程序控制,必须手动申请,手动释放。

栈用来保存定义在函数内的非static对象,如局部变量,仅在其定义的程序块运行时才存在,由编译器自动创建和销毁。

**46.堆和自由存储区的区别?

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数嵌入式工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!

img

img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)

img

最后

资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!

全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

[外链图片转存中…(img-0lYTCRDs-1712393622024)]

[外链图片转存中…(img-RF5a8KL1-1712393622025)]

[外链图片转存中…(img-GRIQ802S-1712393622026)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!

[外链图片转存中…(img-BJxc3cu7-1712393622026)]

[外链图片转存中…(img-i5iPatbr-1712393622027)]

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)

img

最后

资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!

更多资料点击此处获qu!!

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐