sizeof是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。

与strlen的区别:

一、sizeof

是运算符,确切的说是一个编译时运算符,参数可以是数组、指针、类型、对象、函数等。用于统计类型或者变量所占的内存字节数。由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。

二、strlen()

是C标准库中的字符串函数,要在运行时才能计算。参数必须是字符型指针(char*), 且必须是以'\0'结尾的。它的功能是:返回字符串的长度。该字符串可能是自己定义的,也可能是内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符'\0'。返回的长度大小不包括'\0'。

三、实例

1、char *str = "hello";

strlen(str); //它的值是5,因为hello这个字符串有5个字符

sizeof(str); //它的值是4,因为char *是一个指针类型,它占4个字节。

sizeof("hello"); //它的值是5,是因为hello有5个字符,每一个字符占1个字节。

2、int a[2] = {0};

sizeof(a); //它的值是8,因为a中有2个int型变量,每个int型占4个字节,所以8字节

strlen(a) //a相当于一个指针,但是strlen只能接受char*类型,所以编译时出错

3、char arr[10] = "Hello";
              int len_one = strlen(arr);
              int len_two =sizeof(arr); 
              cout << len_one <<" and " << len_two << endl; 
    输出结果为:5 and 10
           strlen只关心存储的数据内容,不关心空间的大小和类型。

sizeof返回定义arr数组时,编译器为其分配的数组空间大小,不关心里面存了多少数据(10x1)。    
   4、char * parr =new char[10];
              int len_one = strlen(parr);
              int len_two = sizeof(parr);
              int len_three = sizeof(*parr);
              cout << len_one <<" and " << len_two << " and " <<len_three << endl;
    输出结果:3 and 4 and 1
      第一个输出结果3实际上每次运行可能不一样,这取决于parr里面存了什么(从parr[0]开始直到遇到第一个'\0'结束);
      第二个结果实际上本意是想计算parr所指向的动态内存空间的大小,但是事与愿违,sizeof认为parr是个字符指针,因此返回的是该指针所占的空间(指针的存储用的是长整型,所以为4)

第三个结果,由于*parr所代表的是parr所指的地址空间存放的字符,所以长度为1。

面试题:定义一个空的数据类型,里面没有任何成员变量和成员函数,对该类型求sizeof,得到的结果是多少?

答案:是1,为什么不是0?空类型的实例中不包含任何信息,本来求sizeof应该是0,但是当我们声明该类型的实例时,它必须在内存中占有一定的空间,否则无法使用这些实例(也就不能求sizeof了),至于占用多少内存,由编译器决定,Visual Studio中每个空类型的实例占用1字节的空间。

扩展1:如果在该类型中添加一个构造函数和析构函数,再求sizeof,得到的结果是多少?

答案:还是1。调用构造函数和析构函数只需要知道函数的地址即可,而这些地址只与类型相关,而与类型的实例无关,编译器也不会因为这两个函数而在实例内添加任何额外的信息。

注:不管添加的是构造函数还是析构函数还是其它任何类型的函数,都是这个结果。

扩展2:那如果把析构函数标记为虚函数呢?

答案:C++的编译器一旦发现一个类型中有虚函数,就会为该类型生成虚函数表,并在该类型的每一个实例中添加一个指向虚函数表的指针,在32位机器上,一个指针占4字节空间,因此求sizeof得到4;如果是64位则为8。测试用例:

[cpp] view plain copy

1.  #include <stdio.h>

2.

3.  struct nullType { };

4.

5.  struct type1

6.  {

7.      type1() {}

8.      ~type1() {}

9.      int print() { printf("Alexia"); return 0; }

10. };

11.

12. struct type2

13. {

14.     type2() {}

15.     virtual ~type2() {}

16. };

17.

18. int main()

19. {

20.     printf("sizeof(nullType) = %d\n", sizeof(nullType));

21.     printf("sizeof(type1) = %d\n", sizeof(type1));

22.     printf("sizeof(type2) = %d\n", sizeof(type2));

23.

24.     return 0;

25. }

原题

代码的优化,给出下一段代码,请做出最好的优化

intf(int n) {

if(n<=4)

return n*n;

else {

return f(n-4)*f(n-1) -f(n-2)*f(n-2);

}

}

解答

无非是将递归转化为循环,防止重复计算中间值,跟斐波那契数列f(n)=f(n-1)+f(n-2)一样,解决方式也一样,就是利用几个临时变量保存中间值,然后每次循环都更新临时变量即可。过程没啥好说的,直接给出代码即可。

intf2(int n) {

int first = 1;

int second = 4;

int third = 9;

int fourth = 16;

if(n<=4)

return n*n;

for(int i = 5; i <= n; ++i) {

int tmp = fourth * first - third * third;

first = second;

second = third;

third = fourth;

fourth = tmp;

}

return fourth;

}

1、局部变量能否和全局变量重名?   

答:能,局部会屏蔽全局。要用全局变量,需要使用 "::"

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

2、如何引用一个已经定义过的全局变量?   

答:可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变量,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。

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

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

4、语句for( ;1 ;)有什么问题?它是什么意思?  

答:和while(1)相同。

5、do……while和while……do有什么区别?   

答:前一个循环一遍再判断,后一个判断以后再循环   

6、请写出下列代码的输出内容   

[cpp] view plain copy

1.  #include <stdio.h>

2.  main()

3.  {

4.  int a,b,c,d;

5.  a=10;

6.  b=a++;

7.  c=++a;

8.  d=10*a++;

9.  printf( "b,c,d:%d,%d,%d",b,c,d);

10. return 0;

11. }

 答:10,12,120

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

答:static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;

static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;

static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

(1)用static定义的全局变量,构成静态的全局变量,若是一个源程序由多个源文件组成,一般的全局变量在各个源文件中都是有效的,而用static修饰的全局变量只在定义该变量的源文件中是有效的,因此static限制了全局变量的作用范围。
(2)普通局部变量在所在的函数每次调用的时候都会被重新分配存储空间,函数结束后,就会回收该存储空间。而用static修饰的局部变量不会,它的值始终保持着。
(3)static函数与普通函数作用域不同,它仅作用于定义它的源文件中。

(4)储存方式:程序的局部变量存在于(堆栈)中,全局变量存在于(静态区/全局区)中,动态申请(new)数据存在于(堆)中。

8.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
  c用宏定义,  #define S(a,b) a*b

c++用inline

引入内联函数的目的是为了解决程序中函数调用的效率问题。内联函数是指用inline关键字修饰的函数。任何在类的说明部分定义的

函数都会被自动的认为是内联函数。

它与一般函数所不同之处只在于函数调用的处理。

内联函数必须是和函数体声明在一起才有效。像这样的申明Inline Tablefunction(int I)是没有效果的,编译器只是把函数作为普通的函数声明,

我们必须定义函数体。

Inline tablefunction(int I) {return I*I}; 这样我们才算定义了一个内联函数。我们可以把它作为一般的函数一样调用。

但是执行速度确比一般函数的执行速度要快。

(C#有无内联函数:C#就没有头文件,哪来的内联外联?要说内联,应该全都是内联,因为所有函数什么的都定义在一个文件里。存在内联函数,但要注意,在何处内联代码的决定完全由CLR做出,我们无法使用像C++中inline这样的关键字来控制那些方法是内联的。)

static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
答:
1) 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
2) 从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。                   
3) static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
综上所述:
static全局变量与普通的全局变量有什么区别:
static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:
static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:
static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

什么是预编译?何时需要预编译?

什么是预编译:

预编译又称为预处理 , 是做些代码文本的替换工作。 
处理以# 开头的指令 , 比如拷贝 #include 包含的文件代码,#define 宏定义的替换 , 条件编译等,就是为编译做的预备工作的阶段。

主要处理#开始的预编译指令,预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。

C 编译系统在对程序进行通常的编译之前,首先进行预处理。 
c 提供的预处理功能主要有以下三种:

1 )宏定义  
2 )文件包含  
3 )条件编译 
何时需要预编译:

总是使用不经常改动的大型代码体。 
程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个“预编译头”

const关键字

const是constant的简写,只要一个变量前面用const来修饰,就意味着该变量里的数据可以被访问,不能被修改。也就是说const意味着“只读”readonly

规则:const离谁近,谁就不能被修改;

const修饰一个变量,一定要给这个变量初始化值,若不初始化,后面就无法初始化。

本质:const在谁后面谁就不可以修改,const在最前面则将其后移一位,二者等效。

const关键字作用:

  1. 为给读你代码的人传达非常有用的信息,声明一个参数为常量是为了告诉用户这个参数的应用目 的;
  2. 通过给优化器一些附加信息,使关键字const也许能产生更紧凑的代码;
  3. 合理使用关键字const可以使编译器很自然的保护那些不希望被修改的参数,防止无意的代码修改,可以减少bug的出现;

const关键字应用

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

C语言 嵌入式 面试小知识点(一)相关推荐

  1. C语言的这个小知识点,竟然连开发多年的老司机都了解的不完全

    printf()和scanf()是 C语言中最"多才多艺"的 I.O函数 它使用的转换说明和转义字符 能使程序员恰到好处的控制 想要输入和输出的信息 但这也提高了使用它的难度 今天 ...

  2. 关于C语言的一些小知识点

    1.memcpy 原型:extern void *memcpy(void *dest, void *src, unsigned int count); 用法:#include <string.h ...

  3. 嵌入式面试知识点总结 -- C语言篇

    如需转载请注明出处:https://juyou.blog.csdn.net/article/details/115716559 之前有写过 日常生活 – 嵌入式面试 ,讲了面试大部分都会问哪些问题. ...

  4. Linux C/C++ or 嵌入式面试之《C/C++笔面试系列》(1) C语言经典笔面试题(上)

    C语言是嵌入式开发的常用语言,也是主要语言,很多企业在招聘嵌入式软件工程师时,C语言的熟练程度是一个重要考察点.笔试也是以C语言为主,所以想要拿到面试机会,还得通过C语言笔试,本专题总结了各大企业C语 ...

  5. C语言小知识点练习总结

    最近在准备C语言的上级考试,之前对C接触不多,在练习过程中把一些小知识点记录下来. 1.字符串的截取 利用strncpy函数,传入三个参数,分别为目标字符串,起始位置,长度. 例如将日期字符串转化为数 ...

  6. C语言实现2048小游戏---粤嵌GE6818嵌入式系统实训

    C语言实现2048小游戏---粤嵌GE6818嵌入式系统实训 实现的全部功能: 功能演示: 版本介绍 简易版--大佬选这个 完整版--想保研.想得高分.想要装逼的同学选这个 至尊版--零基础的.想要装 ...

  7. 【fpga里Verilog语言的小知识点】

    提示:小白撰写,如有错误希望指出 目录 前言 总结 前言 记录一下学习fpga里Verilog语言的小知识点,持续更新. 提示:以下是本篇文章正文内容 1.A = B ? C : D 是一个条件运算符 ...

  8. 嵌入式面试(笔试)笔记2

    嵌入式面试(笔试)笔记2 本文是对于下面链接的B站系列视频的学习笔记 语言笔试题,C++笔试题,嵌入式笔试题,面试题,难点疑点解析(持续更新) 在另外一篇文章的基础上增加或者强调一些对自己更重点的知识 ...

  9. Java面试常见知识点总结

    目录 面试常见知识点 静态代码块 代码块 构造方法之间的顺序 interface和abstract的区别 abstract能不能继承interface 反正可不可以 interface 和abstra ...

最新文章

  1. OpenMP用法大全
  2. 监管发文:规范大学生群体消费贷款,避免陷入消费贷款陷阱
  3. JAVA 将图片转换为Base64编码
  4. linux 搭建.net运行环境,.net core运行环境搭建 linux + windows
  5. 基于RTMP的实时流媒体的QoE分析
  6. SQL Server安全(11/11):审核(Auditing)
  7. mysql导入查询失败_mysql数据库中的查询失败
  8. 又有微软AI科学家流向产业,小鹏汽车迎来视觉感知负责人郭彦东
  9. linux 下的两种软件安装方式 —— 源码(编译、安装),编译好的二进制(直接安装)
  10. c语言开发kafka环境,c++(11)使用librdkafka库实现kafka的消费实例
  11. 最新软件设计师考试大纲
  12. 自己动手写开源爬虫框架 Slit
  13. 时间序列数据的平稳性检验
  14. Java类和对象:private/public/friendly/封装
  15. 文件和文档的比较工具
  16. 利润分配计算机公式,利润与利润分配表计算公式大全
  17. 键盘各种按键对应的ASII码
  18. 蓝屏代码: DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS bootsafe64.sys
  19. 淘宝/天猫关键词搜索最新接口
  20. 2018云南-华为软件产业峰会成功举办 加快构建数字中国

热门文章

  1. Console-算法[for]-国王与老人的六十四格
  2. 学习实践 - 收藏集 - 掘金
  3. 她说程序员不懂浪漫,生日宴上惨变单身狗,其实,程序员的浪漫你不懂!
  4. 使用WinIO库实现保护模式下的IO和内存读写
  5. Azure运维系列 4:安装和使用Azure PowerShell管理云
  6. 从常识看中国经济社会-再续之续:套利
  7. Linux基础(九)--定时任务
  8. 跟着石头哥哥学cocos2d-x(四)--cocos2dx中的动画以及TexturePacker使用
  9. 真格量化——50期权历史波动率策略
  10. Android应用开发—Intent组件详解