2012.07.11

一、简答

1、用预处理指令#define申明一个常数,用以表明1年中有多少秒(忽略闰年问题);写一个“标准#define”宏MIN函数,这个宏输入两个参数并返回最小的一个。

答:#defineSECONDS_PER_YEAR(60*60*24*365)UL

2、用变量a给出下面的定义

a)一个整型数。           

答: int a;

b)一个指向整型数的指针。

 答:int *a;

c)一个指向指针的指针,它指向的指针是指向一个整型数。

 答:int **a;

d)一个有10个整型数的数组

答:int a[10];

e)一个有10个指针的数组,该指针是指向一个整型数的。

 答:int *a[10];

f)一个指向有10个整型数组的指针。

 答:int (*a) [10];

g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数。

 答:int *a(int);

h)一个有10个指针的数组,该指针是指向一个函数,该函数一个整型参数并返回一个整型数。

 答:int (*a[10])(int);

3、关键字volatile有什么含义?并给出三个不同的例子。

答:一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确的说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

例:(1)并行设备的硬件寄存器(如:状态寄存器)

2)一个中断服务子程序中会访问到的非自动变量

3)多线程应用中被几个任务共享的变量

4、结构与联合有何区别?

答:①结构和联合都是由多个不同的数据类型成员组成,但在任何同一时刻,联合中只存放了一个被选中的成员(所有成员共用一块地址空间),而结构的所有成员都存在(不同成员的存放地址不同)。②对于联合的不同成员赋值,将会对其他成员重写,原来成员的只就不存在了,而对于结构的不同成员赋值是互不影响的。

5、求下面函数的返回值(微软)

   int func(x)

   {

       int countx = 0;

       while(x)

       {

            countx ++;

            x = x&(x-1)

       }

       return countx;

   }

答:假定x=9999,答案是8

6、数组与指针的区别?

答:首先对于编译器而言,一个数组是一个地址,一个指针是一个地址的地址。数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。指针可以随时指向任意类型的内存块,远比数组灵活,但也更危险。

7、移位操作为何最好使用无符号数?

答:因为在C语言标准中,只规定了无符号数的移位操作是采用逻辑移位(即左移、右移都是使用的逻辑左移和逻辑右移)。而对于有符号数其左移操作是采用逻辑左移,但右移操作是采用逻辑右移还是算数右移就取决于机器了。(算术右移和逻辑右移的区别是:算术右移不右移符号位,即最高位,右移后前补0还是1取决于符号位的值;逻辑右移执行时将移动符号位,右移后前补0),因此,如果使用了有符号数的右移位操作,它就是不可移植的了。

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

答:①在函数体,一个被申明为静态的变量在这一函数被调用过程中维持其值不变;

②在模块内(但在函数体外),一个被申明为静态的变量可以被模块内所用函数访问。它是一个本地的全局变量;③在模块内,一个被申明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在申明它的模块的本地范围内使用。

9#include<file.h>#includefile.h”的区别?

答:#include<file.h>是用于包含C标准头文件,编译器从标准库路径开始搜索file.h

#includefile.h 是用于你自定义的头文件,编译器从用户的工作路径开始搜索file.h

10、下面const的含义如何?

const int *a;          答:const int的指针。

int const *a;          答:const int的指针。

int *const a;          答:指向int的指针。

int const *const a;     答:指向const对象的const 指针。

11、什么是内存操作越界?

答:所谓内存操作越界,就是指当内存输入超出了预分配空间的大小,就会覆盖该空间之后的一段存储区域,导致系统异常。

12、什么是内存泄漏?造成内存泄漏的原因有哪些?

:所谓的“内存泄露”是指程序在运行时,向系统申请了一段内存空间,C++申请内存空间一般用new,在程序使用完毕后,没有将其释放,系统会认为程序一直在使用,系统就不会让其他程序使用这段内存空间,这样就使系统的可用内存减少,形成“内存泄露”。②动态分配的内存没有释放,比如new出一块内存,没有delete掉,相应的内存就会泄露;类没有析构函数,但类的析构函数是系统默认的,局部对象在生存周期结束之后会自动调用的;malloc没有free一般是链表的删除时会出现。

13、请说出const#define相比,有何优点?

答:①const的使用方法不仅仅是定义常量,还可有定义常对象,常成员函数,用来限制函数参数,函数返回值等;②const的定义是有变量类型的,而#define只是简单的替换,而不能进行调试;③编译器永远也看不到你的宏定义,在进入编译器之前,它已经被预处理器替换掉了;④最基本的,const#define多了一个类型检查。

14、函数式宏定义和函数调用有什么不同?

答:①函数式宏定义的参数没有类型,预处理器只负责做形式上的替换,而不做参数类型检查,所以传参时要格外小心;②调用真正函数的代码和调用函数式宏定义的代码编译生成的指令不同;③函数式宏定义要注意格式,尤其是括号;④若函数参数为表达式,则普通函数的调用与函数式宏定义的替换过程是不一样的;⑤函数式宏定义往往会导致较低的代码执行效率。

15C语言中参数传递有什么特点?我们应当注意些什么?

答:参数传递的特点:①数值传递:被调用函数中对形参的操作不影响主调用函数中的实参值。地址传递:可以通过被调用函数中对形参的操作来修改主调用函数中的实参值。

   注意事项:用malloc new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL 的内存。

16、编写不使用中间变量完成两个数交换的函数,至少两种方法完成。

答:#include<.stdio.h>

Void swap(int *a,int *b,int temp)

{

Temp = *a;

*a = *b;

*b = temp;

}

Int main()

{

   Int a = 5;

   Int b = 7;

   Printf("a=%d\n,b=%d\n",a,b);

   Swap(&a,&b);

   Printf("a=%d\n,b=%d\n",a,b);

17goto语句有什么特点?在C语言中对goto的使用有什么注意事项。

答:特点:goto语句会跳跃到编写程序的任意地点

注意事项:goto语句不能跨越变量的定义向前跳转

18、使用swicth的注意事项。

swtich后面括号内的“表达式”可以是任何类型的数据。每个case的常量表达式的值必须互不相同,否则会产生错误的选择。各个casedefault的出现次序不影响执行的结果。在执行switch语句时,根据switch后面表达式的值找到匹配的入口标号,执行完该case语句后,继续执行下一个case语句,不再进行标号判断。Case常量表达式只起到入口标示的作用。

19、嵌入式系统中经常要用到的无限循环,你怎样使用C编写死循环呢?

答:while(1)      for(;;)

     {                {

        ;                

 }                }

20typedef unsigned char BYTE#defineSTRING char*;哪个更好一些为什么?

答:.typedef unsigned char BYTE更好点。#define只作简单的替换,不作语法检查,而typedef是重命名,不影响定义类型的语法。

21C语言对左值有什么限制?

答:左值不能是常量或表达式。只可以是变量。

22、程序调试中常见的错误有哪些?

答:段错误;拼写错误;符号错误;声明;变量未赋值输入输出的数据类型与所用格式说明符不一致未注意int型数据的数值范围误把“=”作为“等于”运算符,“==”才是关系运算符“等于”;

23、已知函数strcpy的原型是:char *strcpy(char*strDest.const char *strSrc);

a、不调用C的字符串库函数,请编写函数strcpy

bstrcpy能把strsrc的内容复制到strDest,为什么还要char*类型的返回值?

答:a charstrcpy(char * strdest,char * strsrc)

{

     strdest=strsrc;

            while(*strsrc!=’\0’)

            {

*strdest=* strsrc;

strdest++;

strsrc++;

            }       

            strsrc=’\0’;

}

24、什么是野指针?如何避免野指针?

答:野指针不是NULL指针,是指向“垃圾“内存(不可用内存)的指针。

避免野指针的方式:①指针定义后,一定要初始化,如char *p=NULL指针被释放或删除后要设为NULL。如deletep;    If(p=!NULL)    P=NULL;避免指针越界:如指向对象的指针注意对象的生存周期,请在析构函数中注销指针。

25、什么是函数指针?为什么能够使用函数指针,举出一个函数指针使用的例子。

答:函数指针:一个指针声明成为一个指向函数的指针。

   C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上一致的。函数指针有两个用途:调用函数和做函数的参数。

例子:int fun1(char*,int);

int (*pfun1)(char*,int);

pfun1=fun1;

....

inta=(*pfun1)("abcdefg",7);//通过函数指针调用函数。

26、下列语句的作用是什么?

#ifndefHEADER_FILENAME

#idefineHEADER_FILENAME

/*bodyof header*/

#endif

答:语句无效

27、全局变量和局部变量在内存中是否有区别?如果有,是什么区别?

答:在函数内部定义的变量称为局部变量,变量作用域从定义位置开始到本函数结束为止。而在函数之外定义的变量称为全局变量,其作用域从定义变量开始到本源程序文件结束。

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

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

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

答:死循环。条件为1,即为恒真。

30、设有以下说明和定义:

Typedef union {long I;intk[5];char c;}DATE;

struct data

{   int cat;

     DATA cow;

     double dog;

}too;

DATE max;

则语句printf(“%d”,sizeof(struct date)+ sizeof(max));的执行结果是多少?

:结果为:60

31、队列和栈有什么区别?

答:栈必须按“后进先出”的规则进行操作,而队列必须按“先进先出”的规则进行操作;栈只允许在表尾一端进行插入和删除,队列只允许在表尾一端进行插入,在表头一端进行删除。

32、用两个栈实现一个队列的功能?要求给出算法和思路。

答:栈区:由编译器自动分配释放内存,存放函数的参数值,局部变量值等。

    堆区:一般由程序员分配释放内存。堆是向高地址扩展的数据结构,是不连续的内存区域。

33堆和栈的区别?

答:申请方式不同;申请后的系统响应不同;申请大小的限制不同;申请效率的不同;两者存储内容的不同;存取效率的不同

34、要对绝对地址0x100000赋值,我们可以用(unsigned int*0x100000=1234;要么是让程序跳转到绝对地址是0x100000去执行,应该怎么做?

1.*((void (*)( ))0x100000 ) ( );//定义函数指针,并将函数指针的地址置为已知的入口地址,通过调用函数指针来实现对地址的操作

2.0x100000强制转换成函数指针,:(void (*)())0x100000
3.*((void (*)())0x100000)();
在调用该函数指针实现跳转;

35、嵌入式系统中动态分配内存可能发生的问题有哪些?

答:嵌入式系统中动态分配内存可能发生的问题:

  1)忘记释放内存,造成内存泄露。

  2)使用free delete释放了内存后,没有将指针设置为NULL。导致产生“野指针”。

3)内存分配未成功,却使用了它。

4)内存分配虽然成功,但是尚未初始化就引用它。

5)内存分配成功并且已经初始化,但操作越过了内存的边界。

二、找错误并改正

指出下列程序中的问题,说明原因

试题1 

void GetMemory( char *p)

{  p = (char*) malloc( 100 ); }

 void Test(void ) 

{  char *str =NULL;  GetMemory( str ); 

strcpy( str, "hello world" );  printf( str ); }

类型不匹配导致参数传递时出错

void GetMemory( char *p )

{  p = (char*) malloc( 100 ); }

 void Test(void ) 

{  char *str =NULL;  GetMemory( str ); 

strcpy( str, "hello world" );  printf( str ); }

 

试题2

char *GetMemory( void )

{   char p[] ="hello world";   return p;  }  

void Test( void )

{   void *str= NULL;*str GetMemory();   printf(%s,str );  } 

野指针导致段错误

 

试题3

void GetMemory( char **p, int num )

 {  *p = (char *) malloc( num ); } 

void Test( void )

 {  char *str = NULL;  GetMemory( &str, 100 );  strcpy( str, "hello" );   printf( str );  }

三、编程题:

1#include<stdio.h>

#include<stdlib.h>

#define N26

typedefstruct STRUCT

{

char value;

struct STRUCT *next

}

TS

int main()

{

char a[N];

int i;

TS *head,*p;

TS *CreateLinka,N;

for(p=head;p;p=p->next)

printf("%-2c\n",p->value);

put char("\n");

getchar();

return 0;

}

TS *CreateLInk(char *a,int n)

{

   int i;

TS *h,*p;

h = NULL;

fori= n,i>0;i--

{

p = (TS *)malloc(sizeof(TS));

p->value = a[i-1];

p->next = h;

h= p;

}

return h;

}

2.#include<stdio.h>

#include<string.h>

#include<stdlib.h>

intcontinuemax(char *outputstr,char *intputstr)

{  

     int max = 0;

     int count = 0;

     while (*intputstr != '\0')

 {

      while(*intputstr>='0'&&intputstr<= '9'&&*intputste!='\0')

{

 count++;

 intputstr++;

}

   if(max < count)

{

    max =count;

  strncpy(outputstr,intputstr-count,count );

}

   count = 0;

   intputstr++;

}

   Return max;

}

int main()

{

   int num;

   char out_str[100];

   char *in_str = (char *)malloc(100);

   if (in_str ==NULL)

{

     printf("malloc error!\n");

}

   scanf("%s",in_str);

   num = continuemax(out_str,in_str);

   printf("the of num is %d\n",out_str);

   printf("the max num_str is %s\n",out_sttr);

   return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值