[关闭]
@jtahstu 2016-08-21T21:43:46.000000Z 字数 5181 阅读 2395

Interview - C - Summary

C


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

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

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

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

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

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

4、程序的局部变量存在于(堆栈)中,全局变量存在于(静态区 )中,动态申请数据存在于( 堆)中。   

5、Windows消息调度机制是:(C) 

  A.指令队列;B.指令堆栈;C.消息队列;D.消息堆栈;

6、进程和线程的差别。

答:线程是指进程内的一个执行单元,也是进程内的可调度实体.
与进程的区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

7、Heap与stack的差别。

答:Heap是堆,stack是栈。
Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。
Stack空间有限,Heap是很大的自由存储区
C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。
程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行

8、用宏定义写出swap(x,y)

  1. #define swap(x, y)
  2. x = x + y;
  3. y = x - y;
  4. x = x - y;

9、什么是预编译,何时需要预编译:

答: 就是指程序执行前的一些预处理工作,主要指#表示的.
何时需要预编译?
1)、总是使用不经常改动的大型代码体。
2)、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

10、下述三个有什么区别?

  1. char * const p;
  2. char const * p
  3. const char *p

解答:
char * const p; //常量指针,p的值不可以修改
char const * p;//指向常量的指针,指向的常量值不可以改
const char *p; //和char const *p

11、指出下面代码的输出,并解释为什么。(不错,对地址掌握的深入挖潜)

  1. main()
  2. {
  3. int a[5]={1,2,3,4,5};
  4. int *ptr=(int *)(&a+1);
  5. printf("%d,%d",*(a+1),*(ptr-1));
  6. }

输出:2,5
(a+1)就是a[1],(ptr-1)就是a[4],执行结果是2,5
&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)
int *ptr=(int )(&a+1); 则ptr实际是&(a[5]),也就是a+5
原因如下:
&a是数组指针,其类型为 int (
)[5];
而指针加1要根据指针类型加上一定的值,
不同类型的指针+1之后增加的大小不同
a是长度为5的int数组指针,所以要加 5*sizeof(int)所以ptr实际是a[5]
但是prt与(&a+1)类型是不一样的(这点很重要)所以prt-1只会减去sizeof(int*)
a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].

12、写一个“标准”宏,这个宏输入两个参数并返回较小的一个。

答:#define Min(X, Y) ((X)>(Y)?(Y):(X)) //结尾没有;

13、关键字static的作用是什么?

答:1)定义静态局部变量,作用域从函数开始到结束.
2) 在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
3) 在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝

14、关键字const有什么含意?

答 :1)表示常量不可以修改的变量。
2)可以修饰参数,作为输入参数.
3)修饰函数,防止以外的改动.
4)修饰类的成员函数,不改变类中的数据成员.

15、c指针

int *p[n];-----指针数组,每个元素均为指向整型数据的指针。
int (*p)[n];------p为指向一维数组的指针,这个一维数组有n个整型数据。
int *p();----------函数带回指针,指针指向返回的值。
int (*p)();------p为指向函数的指针。

16、C++:memset ,memcpy 和strcpy 的根本区别?

答:#include "memory.h"
memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为' '或'';例:char a[100];memset(a, '', sizeof(a));
memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。
strcpy就只能拷贝字符串了,它遇到'\0'就结束拷贝;例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个'\0'之前)是否超过50位,如超过,则会造成b的内存地址溢出。

17、全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?

答;全局变量的生命周期是整个程序运行的时间,而局部变量的生命周期则是局部函数或过程调用的时间段。其实现是由编译器在编译时采用不同内存分配方法。
全局变量在main函数调用后,就开始分配,
静态变量则是在main函数前就已经初始化了。
局部变量则是在用户栈中动态分配的

18、编写用C语言实现的求n阶阶乘问题的递归算法:

  1. long int fact(int n) {
  2. if(n==0||n==1)
  3. return 1;
  4. else
  5. return n*fact(n-1);
  6. }

19、请说出static和const关键字尽可能多的作用

答:
  static关键字至少有下列n个作用:
  (1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
  (2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
  (3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
  (4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
  (5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
  const关键字至少有下列n个作用:
  (1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
  (2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
  (3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
  (4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
  (5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。

20、二分查找

  1. int binary_search(int* a, int len, int goal) {
  2. int low = 0;
  3. int high = len -1;
  4. while (low <= high) {
  5. int middle = (high - low) / 2 + low; // 直接使用(high + low) / 2 可能导致溢出
  6. if (a[middle] == goal)
  7. return middle;
  8. else if (a[middle] > goal) //在左半边
  9. high = middle - 1;
  10. else //在右半边
  11. low = middle + 1;
  12. }
  13. return -1; //没找到
  14. }
  1. int BinSearch(int Array[],int low,int high,int key) {
  2. if (low<=high) {
  3. int mid = (low+high)/2;
  4. if(key == Array[mid])
  5. return mid;
  6. else if(key<Array[mid])
  7. return BinSearch(Array,low,mid-1,key);
  8. else if(key>Array[mid])
  9. return BinSearch(Array,mid+1,high,key);
  10. } else
  11. return -1;
  12. }
  13. int BinSearch(int Array[],int SizeOfArray,int key) {
  14. int low=0,high=SizeOfArray-1;
  15. int mid;
  16. while (low<=high) {
  17. mid = (low+high)/2;
  18. if(key==Array[mid])
  19. return mid;
  20. if(key<Array[mid])
  21. high=mid-1;
  22. if(key>Array[mid])
  23. low=mid+1;
  24. }
  25. return -1;
  26. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注