C语言面试基础题以及答案

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

#define ONE_YEAR_SENCENDS (365*24*3600)

2. 用预处理指令写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。
#define MIN(a,b) ((a


3.你怎么样用C编写死循环呢?
for(;;){
    
}
while(1){
    
}


4. 用变量a给出下面的定义

a)一个整型数(An integer)

int a;

b)一个指向整型数的指针(A pointer to an integer)

int *a;

c)一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer)

int **a;

d) 一个有10个整型数的数组(An array of 10 integers)

int a[10];

e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers)

int *a[10];

f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)

int (*a)[10]

g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)

int *a( int ){}

h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )

int (* a[10])( int )  //类似这种定义应该采用分解法来做。 先定义单个函数指针 int (*a)(int),然后再是有10个指针的数组 int (*a[10])(int)

5.关键字static的作用是什么?

1)在函数体内,一个被声明为静态的变量在这一函数被调用过程中维持其值不变(该变量存放在静态变量区)。

2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。

3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

2,3统称为隐藏,自己动手写一下就记得住 http://www.cnblogs.com/dc10101/archive/2007/08/22/865556.html)


 6.关键字const是什么含意? 分别解释下列语句中const的作用?

http://www.cppblog.com/xczhang/archive/2008/01/13/41092.html

const int a;  常量a
int const a;  常量a
const int *a;  指针指向的内容不可以被修改   但是指针指向的地址可以修改。
int * const a; 指针指向的地方不可以被改,但是指向的地址的内容可以修改。

int const * const a;  指针指向地址的内容和指针指向的地址都不可以修改。


7. 嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清除a 的bit 3。在以上两个操作中,要保持其它位不变。

#define BIT3 (1<<2)


void setBit3( int a ){

    a |= BIT3;

    printf("%d\n", a);

}

void clearBit3(int a ){

    a &=~BIT3;

       printf("%d\n", a);

}

PS:对负数移位参考   http://zhidao.baidu.com/link?url=gvM7t6D9yqXSqg07DDgGGQXnlCOh_52V6uTXke6h6wTvXAFpI3esKUaIHJKylUS6ozFzJaZoKwEoc9EEpFqQC_


8.下面的代码输出是什么,为什么?
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b > 6)?puts("> 6") : puts("<= 6");

}

大于6.  有符号数转换为无符号数。


9. 评价下面的代码片断:
unsigned int zero = 0;

unsigned int compzero = 0xFFFF;  //FFFF有16bit,不同位数的系统最大数不一样,表示最大数应该使用  ~0 


找错题
试题1:
void test1()
{
char string[10];
char* str1 = "0123456789";
strcpy( string, str1 );

}

//溢出 

试题2:
void test2()
{
char string[10], str1[10];
int i;
for(i=0; i<10; i++)
{
str1[i] = 'a';
}
strcpy( string, str1 );

}

str1没有\0结束符,程序崩溃。

试题3:
void test3(char* str1)
{
char string[10];
if( strlen( str1 ) <= 10 )
{
strcpy( string, str1 );
}
}

改为strlen( str1 ) < 10  这种方式不会报错,但是会造成隐藏的严重bug, 会修改内存里面的数据。


10. 写出字符串strcpy的函数实现过程式.

void strcpy(char * desc, const  char *src ){

while(*(desc+i) ==*(desc+i) );

      for( int i=0; *(src+i)!='\0'; i++){

     *(desc+i) = *(src+i);

}

}


12.请计算sizeof的值和strlen的值。
void func ( char *str )
{
sizeof( str ) = ?
}
char str[10] = “hello”;
strlen(str);

5 8


13.写一个“标准”宏min,这个宏输入两个参数并返回较小的一个。另外,当你写下面的代码时会发生什么事?
least = min(*p++, b);

#define MIN(a,b) ((a
会进行文本替换:  

#define MIN(a,b) ((*p++
可以看到++执行了两次。


14.编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefgh”函数头是这样的:
//pstr是指向以'\0'结尾的字符串的指针
//steps是要求移动的n
void loopmove ( char * pstr, int steps )
{
//请填充...
}


15.这道题目的结果是什么啊?
#include "stdafx.h"
#define SQR(X) X*X
int main(int argc, char* argv[])
{
    int a = 10;
    int k = 2;
    int m = 1;
    a /= SQR(k+m)/SQR(k+m);
    printf("%d\n",a);
    return 0;
}

a =a/ (k+m*k+m/k+m*k+m)

注意文本替换就行,所以宏定义的最佳时间就是对内容加括号。#define SQR(X) (X*X)


16.下面是C 语言中两种if 语句判断方式。请问哪种写法更好?为什么?
int n;
if (n == 10) // 第一种判断方式
if (10 == n) // 第二种判断方式

也是代码的最佳实践问题。  如果按照第一种写法误写成n=10的话会引起bug,第二种这种情况编译器会报错提示。


17.用C写个程序,如何判断一个操作系统是16 位还是32 位的?不能用sizeof()函数。

int a = ~0;//把位数全部设为1
if( a>65536 )  
{
  cout<<"32 bit"<



18.在不用第三方参数的情况下,交换两个参数的值.

a=a+b;

b=a-b;

a=a-b;


或者

a = a^b;

b = a^b;

a= a^b;


19.i 最后等于多少?
int i = 1;
int j = i++;//i = 2, j = 1
if((i>j++) && (i++ == j)) 
i+=j;


20.unsigned short array[]={1,2,3,4,5,6,7};
int i = 3;
*(array + i) = ?

结果是4。

这题考察的好像不是这里,应该考short型移动指针。具体的忘记了。。。。有的编译器short int跟int一样占四个字节。


21.#include 和 #include “filename.h” 有什么区别?

""会首先在当前项目遍历头文件,如果不存在才去系统遍历。

<>的可以改成"",但是""一定不能改成<>


22.编写strcat 函数
已知strcat 函数的原型是char *strcat (char *strDest, const char *strSrc);
其中strDest 是目的字符串,strSrc 是源字符串。
(1) 不调用C 的字符串库函数,请编写函数 strcat。
(2)strcat 能把strSrc 的内容连接到strDest,为什么还要char * 类型的返回值?

#include 
#include 
#include 
char *my_strcat(char *dest,const char *src)  //将源字符串加const,表明其为输入参数
{
	char *strDest=dest;
	assert(dest!=NULL && src!=NULL);       //对源地址和目的地址加非0断言
	//here
	//若使用while(*Dest++),则会出错,指向'\0'之后,会出现dest++,则指向了个'\0'的下一个位置,
	while(*dest !='\0')                   
	{
		dest++;      //循环体内的++可以使指向字符串结束标志'\0'
	}
	while((*dest++=*src++)!='\0');
    return strDest;   ////为了实现链式操作,将目的地址返回
}

int main(void)
{
    char str1[20]="hello";   // sufficent space 
	char str2[]=" world";
	my_strcat(str1,str2);
	printf("%s\n",str1);
	getch();
	return 0;
}

PS:strcat操作一定要切记 目的字符串的空间要足够大,否则会把内存中不属于目的字符串的空间也修改掉。


23.不能做switch()的参数类型是:

只有整数可以做参数。


24.局部变量能否和全局变量重名。

可以重名。 局部变量名会覆盖全局变量名。  C++中可以使用作用域来区分。


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


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

不可以!但是可以声明。 这里涉及到强符号和弱符号的问题,具体的可以参考下面的blog。

在C语言中,函数和初始化的全局变量(包括初始化为0)是强符号,未初始化的全局变量是弱符号。

对于它们,下列三条规则使用:

① 同名的强符号只能有一个,否则编译器报"重复定义"错误。

② 允许一个强符号和多个弱符号,但定义会选择强符号的。

③ 当有多个弱符号相同时,链接器选择占用内存空间最大的那个。

http://blog.csdn.net/astrotycoon/article/details/8008629


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

死循环


28. do……while和while……do有什么区别?

先做还是先判断的区别。


29.请找出下面代码中的所有错误
说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”
#include"string.h"
main()
{
char *src="hello,world";
char *dest=NULL;
int len=strlen(src);
dest=(char*)malloc(len);
char *d=dest;
char *s=src[len];
while(len--!=0)
d++=s--;
printf("%s",dest);
return 0;
}


30.一语句实现x是否为2的若干次幂的判断。

  if ( x & ( x - 1 ) == 0 )
    printf("是2的幂");
  else printf("不是2的幂");

31.下列程序的输出结果:
main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);// (&a+1)指向下一个一维数组
printf("%d,%d",*(a+1),*(ptr-1));
}
解:

这题的关键在int *ptr=(int *)(&a+1);这一句上,&a表示取得数组a存储区域的首地址,再加1表示数组a存储区域的后的地址,这就使得ptr指针指向数组的最后一个元素后面的那个存储单元的地址,而ptr减1后,再进行数据访问,则访问的是ptr指针的前一个存储单元的值,所有最后的答案是2,5

(int *)(&a+1) 强制转化指针类型。

32. char* s="AAA";
printf("%s",s);
s[0]='B';
printf("%s",s);
有什么错?
常量区  不允许修改内容。

33.要对绝对地址0x100000赋值,我们可以用*((unsigned int*)0x100000) =1234;那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?
强制转换指针类型为函数指针。

*(void(*)())0x100000()



34.下面这个程序执行后会有什么错误或者效果:
#define MAX 256
int main()
{
unsigned char A[MAX],i;
for (i=0;i A[i]=i;
}

char是一字节,八位,最大可以表示的整数是255,所以这里死循环了。


35.struct name1
{
char str;
short x;
int num;
}
struct name2
{
char str;
int num; 
short x; 
}
sizeof(struct name1)=?
sizeof(struct name2)=?

http://zhidao.baidu.com/link?url=FMhso6Hf4eeRQN7p2qqzLOBAYPwh6yMJCWOvgmBFTDYWAEZ9ceuREtWhggxtcYG1wtzAM5mNxw6lGFRhxabz-_


36.以下代码中的两个sizeof 用法有问题吗?
void UpperCase( char str1[] ) // 将 str 中的小写字母转换成大写字母
{
int str[5];
for( size_t i=0; i if( 'a' <=str[i] && str[i] <='z' )
str[i] -= ('a'-'A' );
}
char str[] = "aBcDe\0";
printf("%zu",sizeof(str)/sizeof(str[0]));

数组作为形参会被强制转换为指针,所有函数中的sizeof应该改为strlen。 但是这道题本身有问题,考点应该是这个没错。

要校验这道题,可以把str[] = “sdfdsafdsafsadfdsafsadfa”,设置比八字长,就会看到问题



37.请问以下代码有什么问题:
int main()
{
char a;
char *str=&a;
strcpy(str,"hello");
printf(str);
return 0;
}


38.请问以下代码有什么问题:
int main()
{
char a;
char *str=&a;
strcpy(str,"hello");
printf(str);
return 0;
}

没有为a分配内存,并且a是一个字符变量。  内存越界。


39.unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
请问p1+5= ; p2+5= ;


40.判断题
1、有数组定义int a[2][2]={{1},{2,3}};则a[0][1]的值为0。 // 对
2、int (*ptr) (),则ptr 是一维数组的名字。  // 函数指针
3、指针在任何情况下都可进行>, <,>=, <=,==运算。 //不明所以
4、switch(c) 语句中c 可以是int ,long,char ,float ,unsigned int 类型。 //错。  只能是整数,float排除。


41.不使用库函数,编写函数int strcmp(char *source, char *dest) 相等返回0,不等返回-1;


42. 写一函数int fun(char *p)判断一字符串是否为回文,是返回1,不是返回0,出错返回-1。


43.写出程序运行结果
int sum(int a)
{
int c=0;
static int b;
b = 3;//这里应该去掉这句话
c+=1;
b+=2;
return(a+b+c); 
}
void main()
{
int I;
int a=2;
for(I=0;I <5;I++)
{
printf("%d,", sum(a));
}
}
坑哥  这道题有问题!


44.对于下面的函数,要求打印出”hello”,子程序完全正确的是_1 3 4_,
一定能打印出”hello”的是_1 3_,有错误的是_2_
char *GetHellostr(void);
int main(void)
{
char *ps;
ps= GetHellostr( );
if(ps != NULL)
{
printf(ps);
}
return 0;
}
(1)
char *GetHellostr(void)
{
char *ps=“hello”;
return ps;
}
(2)
char *GetHellostr(void)
{
char a[]=“hello”;
return (char *)a;
}
(3)
char *GetHellostr(void)
{
static char a[]=“hello”;
return (char *)a;
}
(4)
char *GetHellostr(void)
{
char *ps;
ps = malloc(10);
if(NULL ==ps) return NULL;
strcpy(ps,”hello”);
return ps;
}


45.下面程序分别只改到一处,就OK了,要求打印出”welcome to saif”
(1)
void main(void)
{
char str1[]=“welcome ”;
char str2[]=“to ”;
char str3[]=“saif ”;
char str[50];
memcpy(str,str1,sizeof(str1));
memcpy(str+sizeof(str1),str2,sizeof(str2));
memcpy(str+strlen(str1)+strlen(str2), str3,sizeof(str3));
printf(str);
}
 (2)
void main(void)
{
char str1[]=“welcome ”;
char str2[]=“to ”;
char str3[]=“saif ”;
char str[50];
memcpy(str,str1, strlen(str1));
memcpy(str+strlen(str1),str2, strlen(str2));
memcpy(str+strlen(str1)+strlen(str2), str3, strlen(str3));
printf(str);
}
46.找出程序中的所有错误
//分配len的长度的内存,内存地址由ptr输出
void test_malloc(char **prt, int len)
{
char *tmp=NULL;
tmp=(char*)malloc(len);
*prt=tmp;
}
void main(void)
{
char *str=“welcome to saif”;
char *buf;
char c=0xff;
test_malloc(&buf, sizeof(str));
if(buf ==NULL)
{
return;
}
strcpy(buf , str);
if( c==(char)0xff)
{
printf(“OK,str=%s”,buf);
}
else
{
printf(“OH my God!”);
}
free(buf);
}


待定吧   除了最后sizeof(str)改为strlen+1 没加free=NULL 其他没看到。。。

你可能感兴趣的:(C)