C语言 ,嵌入式 ,c++,数据结构 面试题目(4)

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

strlen的区别:

一、sizeof

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

二、strlen()

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

三、实例

1char *str = "hello";

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

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

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

     2int a[2] = {0};

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

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

 

3char 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( "bcd%d%d%d"bcd;   

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类型,以使得其返回值不为“左值”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463388.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

把链接伪装成按钮

<input type"button" οnclick"location.hrefhttp://www.lemongtree.net/;" value"GO">转载于:https://www.cnblogs.com/xiaoman_890/archive/2009/07/07/1518471.html

c语言中char *name 与char name 的区别

要点&#xff1a;char* name"abc"指的是常量字符串&#xff0c;不可以修改指针&#xff0c;是兼容老的写法&#xff1b;char[] name"abc"是指针&#xff0c;可以修改&#xff1b; 在学习过程中发现了一个以前一直默认的错误&#xff0c;同样char *c "…

Spring事务配置的五种方式

Spring事务配置的五种方式前段时间对Spring的事务配置做了比较深入的研究&#xff0c;在此之间对Spring的事务配置虽说也配置过&#xff0c;但是一直没有一个清楚的认识。通过这次的学习发觉Spring的事务配置只要把思路理清&#xff0c;还是比较好掌握的。总结如下&#xff1a;…

关于SQL数据库中cross join 和inner join用法上的区别?

使用mysql创建两张表 表a 表b 可以使用下面的脚本创建表&#xff0c;并且添加测试数据&#xff1a; CREATE TABLE a ( name varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, sex varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL D…

CSS实现段落首行缩进、1.5倍行距、左右对齐

.text-content { font-size: 15px; text-indent: 30px; /*段落首行缩进&#xff0c;text-indent的值为font-size的2倍&#xff0c;相当于缩进2个汉字*/ line-height: 22px; /*line-height的值为font-size的1.5倍&#xff0c;即1.5倍行距&#xff0c;使用line-heig…

hash()函数的实现

输入参数都是字符串。 6种hash函数的实现以及使用方式&#xff1a; template<class T> size_t BKDRHash(const T * str) // 该效率最高 { register size_t hash 0; while (size_t ch (size_t)*str) { hash hash * 131 ch; // 也可以乘以31、1…

把数组排成最小的数

题目&#xff1a;输入一个正整数数组&#xff0c;将它们连接起来排成一个数&#xff0c;输出能排出的所有数字中最小的一个。 举例&#xff1a;输入数组{32, 321},则输出这两个能排成的最小数字32132。请给出解决问题的算法&#xff0c;并证明该算法。 答&#xff1a;算法如下&…

【转】 vi常用操作

linux vi命令使用 功能最强大的编辑器——vi vi是所有UNIX系统都会提供的屏幕编辑器&#xff0c;它提供了一个视窗设备&#xff0c;通过它可以编辑文件。当然&#xff0c;对UNIX系统略有所知的人&#xff0c;或多或少都觉得vi超级难用&#xff0c;但vi是最基本的编辑器&#x…

tail的使用

最近找了下tail命令的使用方式&#xff0c;先总结下&#xff1a; tail -f filename 等同于--followdescriptor&#xff0c;根据文件描述符进行追踪&#xff0c;当文件改名或被删除后或者执行ctrlc后&#xff0c;停止追踪 例如&#xff1a;tail -f log/filename.txt ---该…

VS 使用 :新建项目

1.文件位置不放C盘 转载于:https://www.cnblogs.com/duanshouchang/p/10431829.html

C++基础知识友元friend、友元函数和友元类

为了在类之间进行数据共享时&#xff0c;提高效率&#xff0c;C引入了友元的概念。友元主要有三个方面的应用&#xff1a; 将普通函数声明为类的友元函数&#xff1b;将一个类声明为其他类的友元类&#xff1b;将一个类中的成员函数声明为其他类的友元函数。 下面分别介绍。 1、…

Expression Studio 3在windows7下安装失败

Expression Studio 3在windows7下安装失败 Microsoft刚刚发布了Expression Studio 3&#xff0c;我也刚刚下载下来&#xff0c;不过安装就出了问题 双击ExpressionStudio_Trial_en.exe开始解压&#xff0c;开始后就没有了响应&#xff0c;再双击&#xff0c;再解压&#xff0c;…

搞定Linux Shell文本处理工具,看完这篇集锦就够了(转)

Linux Shell是一种基本功&#xff0c;由于怪异的语法加之较差的可读性&#xff0c;通常被Python等脚本代替。既然是基本功&#xff0c;那就需要掌握&#xff0c;毕竟学习Shell脚本的过程中&#xff0c;还是能了解到很多Linux系统的内容。 Linux脚本大师不是人人都可以达到的&a…

出考研初试成绩之后

再次诈尸更新 特殊时期,只憋出来了点压抑的东西来. 考研 考研成绩出来之后就一直没有时间也没有心情写些什么了, 成绩并不好, 可以说是很差了, 好处也有, 就是不用对哪个学校再抱有幻想, 可以专心找工作了.   据说今年的计算机考研人数猛增, 分数也给抬到很高的位置, 以我政治…

Activit系列之---Activity的生命周期

Activity的生命周期 Hello,巴友们好&#xff0c;小菜我又来发博文啦。上篇文章给大家简单的介绍了一下Activity&#xff0c;以及如何创建一个最简单的Activity并且在上面显示hello android! 我们知道要创建一个自己的Activity就必须继承Activity这个类&#xff0c;并且实现它的…

C C++面试常问简答题(1)

1.new、delete、malloc、free关系 delete会调用对象的析构函数,和new对应free只会释放内存&#xff0c;new调用构造函数。malloc与free是C/C语言的标准库函数&#xff0c;new/delete是C的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言&#xff0c…

CSS hack:针对IE6,IE7,IE8,IE9,firefox显示不同效果

区别不同浏览器的CSS hack写法&#xff1a; 区别IE6与其它浏览器&#xff1a; background:orange;_background:blue; 区别IE6与IE7&#xff1a; background:green !important;background:blue; 区别IE6、IE7与FF&#xff1a; background:orange; *background:green…

CAP定理以及证明

历史 这个定理起源于柏克莱加州大学University of California, Berkeley的计算机科学家埃里克布鲁尔在2000年的分布式计算原则研讨会&#xff08;Symposium on Principles of Distributed Computing&#xff08;PODC&#xff09;&#xff09;上提出的一个猜想。 在2002年&…

java线程自带队列的使用以及线程阻塞

java线程&#xff0c;设置队列的大小实现队列阻塞 public class QueueThreads {private static int nThreads 4;//Runtime.getRuntime().availableProcessors() * 2 1;private static BlockingQueue<Runnable> queue new ArrayBlockingQueue<Runnable>(4);//队列…

init/inittab

一、什么是init  init是Linux系统操作中不可缺少的程序之一。 是一个由内核启动的用户级进程。  内核启动&#xff08;已经被载入内存&#xff0c;开始运行&#xff0c;并已初始化所有的设备驱动程序和数据结构等&#xff09;之后&#xff0c;就通过启动一个用户级程序init…