C语言笔试题
1.请填写bool , float, 指针变量 与“零值”比较的if语句。
bool i;
flaot j;
char *p;
if(i);
const float ESPINON=0.00001;
if(j>-ESPINON&&j
if(p==NULL);
2.以下为Linux下的32 位C 程序,请计算sizeof 的值。
char str[]="hello";
char *p=str;
int n=10;
char str1[100];
void *q=malloc(100);
/*
sizeof(str)=6;
sizeof(p)=4;
sizeof(n)=4;
sizeof(str1)=4;
sizeof(q)=4;
*/
在32位系统上,不管指针p指向的是整型数据,还是字符型数据,short型数据,long型数据等,指针p本身所占的内存字节数均为4。
3.用变量a 给出下面的定义
一个有10个指针的数组,类型为int型;
一个指向有10个整型数数组的指针
一个指向函数的指针,该函数有一个整型参数并返回一个整型数;
一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数;
int *a[10];
int (*a)[10];
int *a(int a);
int (*a[10])(int a);
4.设有以下说明和定义
typedef union {long i; int k[5]; char c;} DATE;
struct data { int cat; DATE cow; double dog;} too;
DATE max;
printf("%d",sizeof(struct date)+sizeof(max));
/*
输出:52
解释:
sizeof(max)=20
sizeof(int)=4;
sizeof(double)=4;
*/
5.请问以下代码有什么问题
int main(){
char a;
char *str=&a;
strcpy(str,"hello");
printf(str);
return 0;
}
6. 请问以下代码有什么问题
char* s="AAA";
printf("%s",s);
s[0]='B';
printf("%s",s);
7.int (*s[10])(int) 表示的是什么啊
答案:函数指针数组
8.查问题
void getmemory(char *p){
p=(char *) malloc(100);
strcpy(p,“hello world”);
}
int main( ){
char *str=NULL;
getmemory(str);
printf(“%s/n”,str);
free(str);
return 0;
}
9.会产生什么结果?为什么?
char szstr[10];
strcpy(szstr,"0123456789");
szstr只有10个单元,而复制进来的字符串需要11个单元,导致数组越界
10.数组和链表的区别?
数组:数据顺序存储,固定大小;
链表:数据可以随机存储,大小可动态改变
11.会出现什么问题?打印结果是是多少?
void main(){
char aa[10];
printf(“%d”,strlen(aa));
}
sizeof()和初不初始化,没有关系, strlen()和初始化有关,打印结果值未知。
12.sizeof(A) = ?
struct A
{
char t:4;
char k:4;
unsigned short i:8;
unsigned long m;
}A;
/*
sizeof(A)=8;
原因:位结构体:4+4+8=16位,需要一个int来放
sizeof(int)=4
sizeof(unsigned long)=4
*/
13.求sizeof(name1)?
truct name1{
char str;
short x;
int num;
}name1;
/*
sizeof(char)=1
sizeof(short)=2
sizeof(int)=4
为了保证四字节对齐,shor后面必须留一个字节
*/
truct name2{
char str;
int x;
short num;
}name2;
/*
sizeof(name2)=12
*/
14.程序哪里有错误
wap( int* p1,int* p2 )
{
int * p;
*p = *p1;
*p1 = *p2;
*p2 = *p;
}
15.(void*)ptr和(*(void**))ptr是否相同?
相同
16.对绝对地址0x1000000赋值
(unsigned int*)0x100000 = 1234;
(void (*)())0x100000;//将0x100000强制转换成函数指针
*((void (*)())0x100000)();//调用
17.请问运行Test 函数会有什么样的结果?(内存问题)
void GetMemory(char *p){
p = (char *)malloc(100);
}
void Test(void){
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
答:程序崩溃。 因为GetMemory 并不能传递动态内存, Test 函数中的 str 一直都是 NULL。strcpy(str, "hello world");将使程序崩 溃。---因为str没有空间
char *GetMemory(void){
char p[] = "hello world";//or
char *p="hello world";
return p;
}
void Test(void){
char *str = NULL;
str = GetMemory();
printf(str);
}
char p[] = "hello world"说明使用局部变量定义了一个数组,实际上在堆栈上创建一个临时数组,一旦出子函数,存储空间会被收回,内容被清空
void GetMemory2(char **p, int num){
*p = (char *)malloc(num);
printf("*p=%p\n", *p);
}
void Test(void){
char *str = NULL;
GetMemory(&str, 100);
printf("str=%p\n", str);
strcpy(str, "hello");
printf(str);
}
请问运行Test 函数会有什么样的结果?答:(1)能够输出hello(2)内存泄漏 //没有释放
18.为什么指针变量定义时一定要初始化?
答:因为你首先要理解一点:内存空间需要分配后才可以使用。只是你分配了之后使用才安全。
为什么要进行对他初始化呢
因为指针未被初始化,所以指针所指向的也是随机的,他是个野指针,如果你引用指针,并修改这个指针所指向的内容,而如果这个指针所指向的内容恰好是另外一个程序的数据的话,你将其进行修改了,就会导致另外一个程序可能不能正常运行了.所以使用前一定要进行初始化。
指针变量初始化为NULL是什么意思?
19.关键字volatile有什么含意? 并给出三个不同的例子。
说明这个变量可能会被意想不到地改变。编译器优化时每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份
并行设备的硬件寄存器(如:状态寄存器);
一个中断服务子程序中会访问到的非自动变量;
多线程应用中被几个任务共享的变量;
20.访问决对地址,并赋值
int *p;
p=(int*)0x67a9;
*p=0xaa55;
21.头文件
#ifndef _MAX_h_
#define _MAX_h_
#enif
作用:防止该头文件被重复引用。
22.#include 和#include “filename.h” 有什么区别?
#include :指定目录寻址(标准库)
#include “filename.h”:优先工作路径寻找,找不到,找工作路径
23.const 有什么用途?(请至少说明两种)
可以定义const
常量
const 可以
修饰函数的参数、返回值,甚至函数的定义体。
作用:被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
24.static有什么用途?
static修饰全局变量:限制变量的作用域:只能在当前文件使用。其他文件要使用需要extern声明
static修饰局部变量,限制存储域,只能在定义这个变量的函数中使用,其他函数无使用权使用,并且也初始化一次
25.堆栈溢出一般是由什么原因导致的?
【标准答案】没有回收垃圾资源。
26.如何引用一个已经定义过的全局变量?
引用头文件,在头文件里面使用extern对变量进行声明
直接在使用出使用extern对变量进行声明
27.全局变量可不可以定义在可被多个.C 文件包含的头文件中?为什么?
不能,这将导致变量被重复编译。但是可以在头文件里对这个变量使用static进行声明,限制该变量的作用域
28.队列和栈有什么区别?
【标准答案】队列先进先出,栈后进先出
29.Heap与stack的差别。
heap是堆,stack是栈
Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。
Stack空间有限,Heap是很大的自由存储区
C 中的malloc 函数分配的内存空间即在堆上
30.用宏定义写出swap(x,y),即交换两数。
#define swap(x,y) \
(x)=(x)+(y);\
(y)=(x)-(y);\
(x)=(x)-(y);
31.写一个“标准”宏,这个宏输入两个参数并返回较小的一个。
# define min(x,y) (x)
32.带参宏与带参函数的区别
带参的宏
带参的函数
处理时间
编译时
运行时
参数类型
无
需要定义
程序长度
边长
不变
处理过程
不占用
占用
运行时间
不占运行时间
调用和返回时占
33.已知一个数组tabl e ,用一个宏定义,求出数据的元素个数。
#define num(table) (sizeof(table)/sizeof(table[0]))
34.static的问题
A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?
【标准答案】static的全局变量,表明这个变量仅在本 模块中有意义,不会影响其他模块。他们都放在静态数据区,但是编译器对他们的命名是 不同的。 如果要使变量在其他模块也有意义的话,需要使用extern 关键字。
static全局变量与普通的全局变量有什么区别?
普通全局变量:可以作用于多个文件
static全局变量:只进行一次初始化,作用域在当前.c文件,其他.c文件无权调用
static局部变量和普通局部变量有什么区别?
普通局部变量:生存周期仅仅在函数内,函数运行完毕则不存在
static局部变量:实际上是一个静态全局变量,只初始化一次,下一次接着上一次的值使用
static函数与普通函数有什么区别?
普通函数:默认为extern 。可以在整个工程里面使用
static函数:仅仅用于本文件。其他.c文件无权使用。其他文件也可以和它使用相同的函数名,互相没有联系
程序的局部变量存在于栈中,全局变量存在于静态数据区中,动态申请数据存在于_堆中。
35.什么是预编译,何时需要预编译?
总是使用不经常改动的大型代码体
程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。
三种预处理:宏定义,文件包含,条件编译
36.对于一个频繁使用的短小函数。c语言怎么实现?
c用宏定义
37.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
#define year_all_s (60 * 60 * 24 * 365)
printf("s=%ul\n", year_all_s);
38.#define和typedef的问题
Typedef 在C 语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如,思考一下下面的例子:
#define dps struct s*
typedef struct s* tps;
以上两种情况的意图都是要定义dPS 和tPS 作为一个指向结构s指针。哪种方法更好呢?(如果有的话)为什么?
typedef struct s* tps好!
假如:
#define dps struct s*
typedef struct s* tps;
dps p1,p2;
tps p3,p4;
扩展dpsstruct s* p1,p2说明:p1为一个指向结构的指针,p2为一个实际的结构体。
39.请简述以下两个for 循环的优缺点。
for (i=0; i
{
if (condition)
DoSomething();
else
DoOtherthing();
}
if (condition)
{
for (i=0; i
DoSomething();
}
else
{
for (i=0; i
DoOtherthing();
}
方案一:
优点:程序简洁
缺点:多执行了N-1次逻辑判断,并且打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。
方案二:
优点:循环的效率高
缺点:程序不简洁
40.语句for( ;1 ;) 有什么问题?它是什么意思?
标准答案】死循环,和while(1)相同。
do……while和while……do有什么区别?
标准答案】前一个:循环一遍再判断;后一个:判断以后再循环。
41.程序输出值
#include
int main(){
int a,b,c,d;
a=10;
b=a++;
c=++a;
d=10*a++;
printf("b,c ,d:%d,%d,%d",b,c,d );
return 0;
}
/*
b=10;
c=12;
d=120;
*/
int main(void){
unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
printf("p1+5=%p\n",p1+5);
printf("p2+5=%p\n",p2+5);
}
/*
p1+5=0x801005;
p2+5=0x810014
*/
int main(void){
int a[5]={1,2,3,4,5};
/*
此时a作为数组的首地址,+1的跨度为整个数组的长度,
ptr指向数组a后面的空间地址。
*/
int * ptr=(int*)(&a+1);
printf("a=%p, ptr=%p\n",a,ptr);
printf("%d,%d",*(a+1),*(ptr-1));
}
/*
结果:2 5
*/
42.判断程序的错误
int a[60][250][1000],i,j,k;
for(k=0;k<1000;k++)
for(j=0;j<250;j++)
for(i=0;i<60;i++)
a[i][j][k]=0;
修改
int a[60][250][1000],i,j,k;
for(i=0;i<60;i++)
for(j=0;j<250;j++)
for(i=0;i<60;i++)
编译的时候没错,运行的时候可能出错,因为这个数组太大,如果放在栈中,会溢出,要作为全局变量。
43.求一个数的平方的程序,请找出错误
#define SQUARE(a)((a)*(a))
int main(){
int a=5;
int b;
b=SQUARE(a++);
printf("a=%d\tb=%d\n",a,b);
}
/*
运行环境:DEV++ 32位
a=7;
b=30;
*/
结果因编译器,可能不同
宏在预编译时会以替换的形式展开,仅仅会替换。涉及到宏的地方,不要用++-- ,标准中对此没有规定。
44.这段代码执行有什么问题?
#define Max_CB 500
void LmiQueryCSmd(Struct MSgCB *pmsg){
unsigned char ucCmdNum;
......
for(ucCmdNum=0;ucCmdNum
{
......;
}
}
【标准答案】死循环
unsigned char //无符号字符型表示范围0~255;char // 有符号字符型 表示范围-128~127 因此:ucCmdNum永远不可能小于500
45.编写死循环
while(1)
for(;;)
46.程序分析
int modifyvalue(){
int x=10;
return(x+=10);
}
int changevalue(int x ){
return(x+=1);
}
void main(){
int x=10;
x++;
changevalue(x);
x++;
modifyvalue();
printf("First output:%d\n",x);
x++;
changevalue(x);
printf("Second output:%d\n",x);
modifyvalue();
printf("Thirdoutput:%d\n",x);
}
/*
First output:12
Second output:13
Thirdoutput:13
*/
47.switch()的参数类型只能是整形
48.一语句实现x是否为2 的若干次幂的判断
#define is2(x) ((x)&(x-1))? "NO":"YES"
int main(void){
int i,j;
scanf("%d",&i);
printf("%s\n",is2(i));
}
如果是2的若干次幂就表示它只有一位是1,m&(m-1)一定为0; 否则大于0。
49.一段中断函数
__interrupt double compute_area (double radius){
double area = PI * radius * radius;
printf(" Area = %f", area);
return area;
}
错误
中断函数没有输入参数
中断函数没有返回值
中断函数应该简短有效,计算浮点数不明智
50.下面的代码输出是什么,为什么?
int main(void){
unsigned int a = 6;
int b = -20;
(a+b> 6)? puts("> 6") : puts("<= 6");
}
/*
结果:>6
/*
原因:当表达式中存在有符号类型和无符号类型时所有 的数都自动转换为无符号类型。因此-20 变成了一个非常大的正整数。
51.编写strcpy 函数
已知strcpy 函数的原型是 char *strcpy(char *strDest, const char *strSrc);其中strDest是目的字符串,strSrc 是源字符串。
char *strcpy(char *strDest, const char *strSrc)//源字符串参数用const修饰,防止修改源字符串;{
if(strDest||strSrc)//空指针检查
return 0;
else{
char *t;
t=strDest;//目的指针dst已经在进行移动了,所以用辅助指针t表明首指针;
while(strSrc)//遇到'\0'将会停止;
{
*strDest++=*strSrc++;
}
return t;
}
}
52.写出二分查找的代码。
/*
输入:
arr:数组指针(数组升排列)
length:数组长度
n:查找数
输出:
查找数的下标
*/
int binary_search(int* arr, int length, int n){
int head=0,tail=length-1,mid;
while(head<=tail)
{
mid=(head+tail)>>1;
if(arr[mid]
{
head=mid+1;
}
else if(arr[mid]>n)
{
tail=mid-1;
}
else return mid;
}
return -1;
}
int main(void){
int a[10]={1,2,3,4,5,6,7,8,9,10};
int i;
printf("查找数:\n");
scanf("%d",&i);
printf("下标:%d\n",binary_search(a,10,i));
}
53.请编写一个C 函数,该函数给出一个字节中被置1 的位的个数。
/*
输入:字节
输出:字节中1的个数
*/
unsigned int TestAsOne1(char log){
unsigned int num=0,i;
for(i=0;i<8;i++)
{
if(log&(0x80>>i))
num++;
}
return num;
}
int main(void){
char i=10;
scanf("%c",&i);
printf("1的个数:%u\n",TestAsOne1(i));
}
54.请编写一个C 函数,该函数将给定的一个字符串转换成整数。
/*
输入:字符串
输出:字符串表示的整数
*/
int insert(char *str){
int num=0,digital;
if(&str==NULL)
return -2;
while(*str)
{
if(*str>'0'&&(*str
{
digital=*str-48;
num=num*10+digital ;
str++;
}
else return -1;
}
return num;
}
void main(){
char *str1 ="12536343";
printf("字串:%s\t对应整数:%d\n",str1,insert(str1));
}
55.请编写一个C 函数,该函数将给定的一个整数转换成字符串
#include
#include
#include
#include
char* int_to_char(int a){
int flag=0,length=0;
int a1;
int i;
char *str;
if(a<0)//判断正负
{
flag=-1;
a=abs(a);
a1=a;
length++;
}
else a1=a;
while(a)//计算整数长度
{
a=a/10;
length++;
}
str=(char*)malloc((length+1)*sizeof(char));//分配地址空间
printf("length=%d\n",length);
if(flag)//整数为正数
{
str[0]='-';
for(i=length-1;i>0;i--)
{
str[i]=a1%10+48;
a1=a1/10;
}
str[length]='\0';
}
else{//整数为负数
for(i=length-1;i>=0;i--)
{
str[i]=a1%10+48;
a1=a1/10;
}
str[length]='\0';
}
return str;
}
int main(void){
int a=123456;
char *str=NULL;
str=int_to_char(a);
printf("a=%d\n",a);
printf("str=%s\n",str);
}
56.实现strcmp 函数。
要求:两个字符串相等,输出0,str1>str2,输出1,str1
#include
#include
#include
#include
int str_cmp(const char *str1,const char *str2){
if(str1==NULL||str2==NULL)
return 11;
while(*str1)
{
if(*str1++>*str2++)
return 1;
if(*str1++
return -1;
}
return 0;
}
int main(void){
char *str1="qce1234";
char *str2="qbe123";
printf("\t%d\n",str_cmp(str1,str2));
}
57.请编写一个C 函数,该函数将一个字符串逆序。
#include
#include
#include
#include
char* back_out(const char *a){
int length,i;
char *str;
if(a==NULL)
return NULL;
length=strlen(a);
str=(char*)malloc(length+1);
for(i=length-1;i>=0;i--)
{
str[i]=a[length-1-i];
}
str[length]='\0';
return str;
}
int main(void){
char *str="!@#$%^&*()_+Qscvt5567";
char *str1;
printf("\t原序:%s\n",str);
str1=back_out(str);
if(str1)
printf("\t倒序:%s\n",str1);
else printf("Error:输入参数未初始化!");
}
#### 58.请编写一个C 函数,该函数在给定的内存区域搜索给定的字符,并返回该字符所在位置索引值。
#include
#include
#include
#include
int search(char *a,int length,char s){
int local,i;
for(i=0;i
{
if(a[i]==s)
return i;
}
return -1;
}
int main(void){
char b[10]={'q','a','c','d','1','%','t','F','C','7',};
char search_c='7';
printf("\t%d\n",search(b,10,search_c));
}
59.请编写一个C 函数,该函数在一个字符串中找到可能的最长的子字符串,该字符串是由同一字符组成的。
#include
#include
#include
#include
char* find_max_long(char *a){
int length,i;
int submax=1;
char submax_c;
char *max;
max=(char*)malloc(2);
max[0]=1;
length=strlen(a);
printf("length=%d\n",length);
for(i=0;i
{
if(a[i]==a[i+1])
{
submax++;
submax_c=a[i];
}
else {
if(max[0]
{
max[0]=submax;
max[1]=submax_c;
}
submax=1;
}
}
return max;
}
int main(void){
char *str="helllllo2222222qqqqggggggggzzzzzzzzzz";
char *aim;
aim=find_max_long(str);
printf("重复个数:%d\n",*aim);
printf("最长字串:%c\n",*(aim+1));
}
60.有一浮点型数组A, 用C 语言写一函数实现对浮点数组A进行降序排序,并输出结果,要求要以数组A 作为函数的入口.
#include
#include
#include
#include
void double_sort(float *a,int length){
int i,j;
printf("length=%d\n",length);
for(i=0;i
{
for(j=0;j
{
if(a[j]>a[j+1])
{
a[j]=a[j]+a[j+1];
a[j+1]=a[j]-a[j+1];
a[j]=a[j]-a[j+1];
}
}
}
}
void main(){
int i;
float a[10]={1.1,2.2,9.6,7.5,2.0,6.6,55.23,0.014,56.123456,1.2};
double_sort(a,10);
for(i=1;i
{
printf("%f\t",a[i]) ;
}
}
61.有1、2、3 、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少。
#include
#include
#include
#include
int main(void){
int a[4]={1,2,3,4};
int i,j,k;
int num=0;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
for(k=0;k<4;k++)
{
if(i!=j&&i!=k&&j!=k)
{
num++;
printf("%d\t",a[i]*100+a[j]*10+a[k]);
}
}
}
}
printf("\n个数:%d\n",num);
}