c语言笔记第八天:c语言面试题大全
c语言笔记第八天:c语言面试题大全。
1.static有什么用途?
1.限制变量的作用域
2.设置变量的存储域
2.引用与指针有什么区别?
1) 引用必须被初始化,指针不必。
2) 引用初始化以后不能被改变(指的是指向的地址不可变),指针可以改变所指的对象。
#include
int main()
{
int a=5,b=6;
int &j=a;
j=b;
printf("%d %d\n",j,a);
return 0;
}
输出结果为6 6.
2) 不存在指向空值的引用,但是存在指向空值的指针。
3.
全局变量和局部变量在内存中是否有区别?如果有,是什么区别?
全局变量储存在静态数据库,局部变量在堆栈
4.
冒泡排序算法的时间复杂度是什么?
O(n^2)
5.
写出float x 与“零值”比较的if语句。
if(x>0.000001&&x<-0.000001)
6.
局部变量能否和全局变量重名?
答:能,局部会屏蔽全局。要用全局变量,需要使用"::"
局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内
7.
如何引用一个已经定义过的全局变量?
答:extern
可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错
8、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?
答:可以,在不同的C文件中以static形式来声明同名全局变量。
可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错
9、语句for( ;1 ;)有什么问题?它是什么意思?
答:和while(1)相同。
10、do……while和while……do有什么区别?
答:前一个循环一遍再判断,后一个判断以后再循环
11.
static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。
static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
12、程序的局部变量存在于(堆栈)中,全局变量存在于(静态区 )中,动态申请数据存在于( 堆)中。
13.
1、栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;
2、堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
队列和栈有什么区别?
队列先进先出,栈后进先出
14.
请找出下面代码中的所以错误
说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”
1、#include"string.h"
2、main()
3、{
4、 char*src="hello,world";
5、 char* dest=NULL;
6、 int len=strlen(src);
7、 dest=(char*)malloc(len);
8、 char* d=dest;
9、 char* s=src[len];
10、 while(len--!=0)
11、 d++=s--;
12、 printf("%s",dest);
13、 return 0;
14、}
答:
方法1:
int main(){
char* src = "hello,world";
int len = strlen(src);
char* dest = (char*)malloc(len+1);//要为/0分配一个空间
char* d = dest;
char* s = &src[len-1];//指向最后一个字符
while( len-- != 0 )
*d++=*s--;
*d = 0;//尾部要加/0
printf("%s/n",dest);
free(dest);// 使用完,应当释放空间,以免造成内存汇泄露
return 0;
}
方法2:
#include
#include
main()
{
char str[]="hello,world";
int len=strlen(str);
char t;
for(int i=0; i{
t=str[i];
str[i]=str[len-i-1]; str[len-i-1]=t;
}
printf("%s",str);
return 0;
}
16.
什么是预编译
何时需要预编译:
1、总是使用不经常改动的大型代码体。
2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。
char * const p;
char const * p
const char *p
上述三个有什么区别?
char * const p; //常量指针,p的值不可以修改
char const * p;//指向常量的指针,指向的常量值不可以改
const char *p; //和char const *p
17.
请问以下代码有什么问题:
int main()
{
char a;
char *str=&a;
strcpy(str,"hello");
printf(str);
return 0;
}
没有为str分配内存空间,将会发生异常
问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。
18.
关键字static的作用是什么?
定义静态变量
关键字const有什么含意?
表示常量不可以修改的变量。
19.
char szstr[10];
strcpy(szstr,"0123456789");
产生什么结果?为什么?
长度不一样,会造成非法的OS
20.
类的静态成员和非静态成员有何区别?
类的静态成员每个类只有一个,非静态成员每个对象一个
21.
数组和链表的区别
数组:数据顺序存储,固定大小
链表:数据可以随机存储,大小可动态改变
22.
#include
int main()
{
typedef struct
{
int a:2;
int b:2;
int c:1;
}test;
test t;
t.a = 1;
t.b = 3;
t.c = 1;
printf("%d",t.a);
printf("%d",t.b);
printf("%d",t.c);
return 0;
}输出结果为1-1-1
t.a为01,输出就是1
t.b为11,输出就是-1
t.c为1,输出也是-1
3个都是有符号数int嘛。
这是位扩展问题
01
11
1
编译器进行符号扩展
#include
int main()
{
typedef struct
{
int a:2;
int b:2;
int c:1;
}test;
test t;
t.a = 1;
t.b = 2;
t.c = 1;
printf("%d",t.a);
printf("%d",t.b);
printf("%d",t.c);
return 0;
}输出结果为1-2-1
什么是预编译?何时需要预编译?
答:
预编译又称预处理,是整个编译过程最先做的工作,即程序执行前的一些预处理工作。主要处理#开头的指令。如拷贝#include包含的文件代码、替换#define定义的宏、条件编译#if等。.
何时需要预编译:
1、总是使用不经常改动的大型代码体。
2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。
23.
static关键字的作用?
答:
Static的用途主要有两个,一是用于修饰存储类型使之成为静态存储类型,二是用于修饰链接属性使之成为内部链接属性。
1静态存储类型:
在函数内定义的静态局部变量,该变量存在内存的静态区,所以即使该函数运行结束,静态变量的值不会被销毁,函数下次运行时能仍用到这个值。
在函数外定义的静态变量——静态全局变量,该变量的作用域只能在定义该变量的文件中,不能被其他文件通过extern引用。
2 内部链接属性
静态函数只能在声明它的源文件中使用。
24.
char *p="abc”;//在常量区,不可改变
char a[3]="abc”;//在栈区,可以改变
25.
两个字符串,s,t;把t字符串插入到s字符串中,s字符串有足够的空间存放t字符串
void insert(char *s, char *t, int i)
{
memcpy(&s[strlen(t)+i],&s[i],strlen(s)-i);
memcpy(&s[i],t,strlen(t));
s[strlen(s)+strlen(t)]='\0';
}
26.
一般将数据结构分为两大类型:线性结构与非线性结构。线性表、栈与队列、线性链表都是线性结构,而二叉树是非线性结构。
c语言规定,实参变量对形参变量的数据传递是“单向值传递”,只由实参传给形参。在内存中,实参单元与形参单元是不同的单元。调用结束后,实参单元仍保留并维持原值。
下面程序输出的结果是__________。
main()
{
int i=5,J=9,x;
x=(I==j?i:(j=7));
printf(”\n%d,%d”,I,J);
}
A)5,7 B)5,5 C)语法错误 D)7,5
答案:A
评析:条件表达式的一般形式为:表达式I?表达式2:表达式3;先求解表达式1,若为真则求解表达式2;若表达式l的值为假,则求解表达式3。本题中先判断i==j,不等,执行j=7;然后执行x=7。故本题为A。
(19)若执行下面程序时从键盘上输入5,
main()
{
int x:
scanf(”%d”,&x);
if(x++>5)printf(”%d\n”,x);
else printf(”%d\n”,x–);
}
则输出是________。
A)7 B)6 C)5 D)4
答案:B
评析:根据c语言的语法,x++是在使用x之后,再将x的值加1,在if语句中,x的值为5,条件不成立,执行else后面的语句,因为x的值已经加1,为6,所以打印结果为6。
(20)若有以下定义和语句:
int a[]={l,2,3,4,5,6,7,8,9,10},*p=a;
则值为3的表达式是_________。
A)p+=2,*(p++) B)p+=2,*++p
C)p+=3,*p++ D)p+=2,++*p
答案:A
评析:引用一个数组元素,可以用:(1)下标法,如a[i]形式;(2)指针法,如*(a+i)或*(p+i)。数组的下标从0开始,值为3的数组元素是a[2]。B、c的内容为a[3],D将a[2]前自加,结果为4。
(21)设a、b和c都是int型变量,且a=3、b=4、c=5,则下面的表达式中,值为0的表
达式是___________。
A)’a’&&’b’ B)a<=b C)a‖+c&&b-c D)!((a
答案:D
评析z选项A:‘a’&&‘b’是字符a与b的相与,不为0;选项B:a<=b,由题中变量赋值可知,结果为1。选项c:a‖+c&&b-c,结果为1;选项D:!((a
(22)以下程序运行后,输出结果是_________。
main()
{
char*d[]。{“ab”,”cde”};
printf(”%x”,d[1]);
}
A)cde B)字符c的ASCII码值
C)字符c的地址 D)出错
答案:C
评析:指针数组中的每一个元素都相当于一个指针变量。一维指针数组的定义形式为:类型名+数组名[数组长度],在本题main函数中定义指针数组d,它有两个元素,其初值分别是“ab”、“cde”的首地址。dB]的值为”cde”的首地址。%x是指以十六进制数形式输出整数。
(23)设有如下程序
#include
main()
{
int**k,*j,i=100;
j=&i; k=&j;
printf(”%d\n”,**k);
}
上述程序的输出结果是________。
A)运行错误 B)100 C)i的地址 D)j的地址
答案:B
评析:j=&i,j的值就是i的地址,*j=100,将j的地址赋给k,这时*k=j,那么,**k=*j,而1=100,所以**k=100,最后的打印结果应当为100。
(24)设有以下语句,其中不是对a数组元素的正确引用的是:_______(其中O≤i<10)
int a=[10]={0,1,2,3,4,5,6,7,8,9,},*p=a;
A)a[p-a] B)。(&a[i]) C)p[I] D)*(*(a+i))
答案:D
评析:观察程序可知,a实际上就是数组a的首地址,所以“+(a+i)”表示的就是数组a中的第i个元素的值,进而,我们可以知道+(t(a+i))必然不是对a数组元素的正确引用。
(25)以下程序运行后,输出结果为________。
main()
{
int a[2][3]={1,3,5,7,9,1 1},*s[2],**pp,*p;
s[0]=a[0],s[1]=a[1];
pp=s;
p=(int*)malloc(sizeof(int));
**pp=s[1][1];
p=*PP;
printf(”%d\n”,*p);
}
A)l B)7 C)9 D)1l
答案:C
评析:s是一个含有两个元素的指针数组,pp是一个指向指针变量的指针,s[O]是指向二维数组a行下标为0的元素的首地址,即a[0儿0]的地址,s[1]为a[1][0]的地址。pp的值为s[O]的地址。**pp=s[1][l]后,a[0][0]的值将被赋值为all][l]的值,执行p=*pp;后,p中将是s[0]的值,最后的输出语句将输出地址s[0]所指向的数据,即a[0][O]。
(26)有以下程序:
#include
main(){
char c[6];
int I=0:
for(;i<6;c[-]=getchar(),i++);
for(I=0;i<6;i++)putchar(c[i]);
primf(”\n”);
}
如果从键盘上输入:
ab
c
def
则输出结果为_________.
A)a B)a C)ab D)abcdef
b b c
c c d
d d
e
f
答案:C
评析:1.getchar():此函数的作用是从终端(或系统隐含指定的输入设备)输入一个字符。
2.putchar():此函数的作用是向终端输出一个字符,也可以输出控制字符。
本题在输入字符时,ab和c后面的回车符分别赋给了c[2]和e[4],所以,正确答案为c。
(27)在调用函数时,如果实参是简单变量,它与对应形参之间的数据传递方式是_______。
A)地址传递 B)单向值传递
C)由实参传递给形参,再由形参传递给实参
D)传递方式由用户指定
答案:B
评析:c语言规定,实参变量对形参变量的数据传递是“单向值传递”,只由实参传给形参。在内存中,实参单元与形参单元是不同的单元。调用结束后,实参单元仍保留并维持原值。
(28)下面程序
#include
#include
main()
{ char*p1=”abc”,*p2=”ABC”,str[50]=”xyz”;
strcpy(str+2,strcat(p1,p2));
printf(”%s\n”,str);
}
的输出是_________。
A)xyzabcABC B)zabcABC
C)yzabcABC D)xyabcABC
答案:D
评析:strcat(pl,p2)将字符串abcABC放到了*pl所指向的存储单元中;strcpy在本题将abcABC复制到str+2所指向的存储单元中,即覆盖原str数组中的字符z及其后的所有字符,故str的值为”xyabcABC”。
(29)下面程序
int aa[3][3]:{{2},{4},{6}};
main()
{ int i,*p:&aa[0][0];
for(I=0;i<2;i++){
if(i==0)aa[I][i+l]=*p+1;
else++p;
printf(”%d’.,。p);
}
}
的输出是__________。
A)23 B)26 C)33 D)36
答案:A
评析:观察题目,可以发现,*p=&aa[01[o]语句实际是将数组aa的首地址赋给了指针变量p,将i的值带入for循环中,i=0时,aa[0][1]=3,+p=2;*p输出的是指针所指向的数组值,此时p所指向的是aa[O][O],输出2,而i=l时执行了++p操作使指针向后移动指向了aa[O儿1],所以在输出*p时应为3。
(30)以下程序的输出结果是_________。
#include
#include
fun(char*w,int n)
{
char t,*s1,*s2;
s1=w;s2=w+n-l:
while(s1
{
t=*s1++:
*sl=*s2–;
*s2=t;
}
}
main()
{
char*p;
p=”1234567″;
fun(p,strlen(p));
puts(p);
}
A)1234567 B)7654321 C)1711717 D)717717l
答案:C
评析:在子函数fun中,sl为字符串w的起始地址,s2为字符串的结束地址(字符‘\O’除外),当执行循环结束循环,w=“1711717”。