C语言面试题(二)
4.一个32位的机器,该机器的指针是多少位 2^32 =4G
8位处理器、16位处理器、32位处理器和64位处理器,其计数都是8的倍数。它表示一个时钟周期里,处理器处理的二进制代码数。“0”和“1”就是二进制代码,线路上有电信号,则计做1,没有电信号则为0。8位机有8条线路,每个时钟周期有8个电信号,组成一个字节。所以,随8位处理器上升至64位处理器,每个时钟周期传送1个字节到8个字节,关联到时钟速度提高到若干个千兆赫之后,处理器处理信息的能力越来越大。
CPU的一次基本运算 (and, or, xor,not),能处理/运算几个 bits. 64bits data 交由 32-bit CPU 去运算, 得分两次才行.
main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);//指针是数组类型,+1相当于加20.如果是(a+1)是+4
printf(“%d %d”,a,ptr);
printf("%d,%d",*(a+1),*(ptr-1));
}
输出:1245036 1245056 2,5
6.请问以下代码有什么问题:
1).
intmain()
{
char a;
char *str=&a;
strcpy(str,"hello");
printf(str);
return 0;
}
答;没有为str分配内存空间,将会发生异常
2).
char*s="AAA";//常量的内容不能改,可定义为数组
printf("%s",s);
s[0]='B';
printf("%s",s);
有什么错?
答: "AAA"是字符串常量。s是指针,指向这个字符串常量,所以声明s的时候就有问题。
cosnt char* s="AAA";
然后又因为是常量,所以对是s[0]的赋值操作是不合法的。
7.用变量a给出下面的定义
a)一个整型数(An integer) b) 一个指向整型数的指针(A pointer to an integer) c) 一个指向指针的的指针,它指向的指针是指向一个整型数(Apointer to a pointer toan integer) d) 一个有10个整型数的数组(An array of 10integers) e) 一个有10个指针的数组,该指针是指向一个整型数的(Anarray of 10 pointers to integers) f) 一个指向有10个整型数数组的指针(A pointerto an array of 10integers) g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a functionthat takes an integer as an argument andreturns an integer) h) 一个有10个函数指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integerargumentand return an integer )
答案是:
Int (*p[10])(int);a) inta; // An integer b) int *a; // A pointer to an integer c) int **a; // A pointer to a pointer to an integer d) int a[10]; // An array of 10 integers e)int*a[10];// An array of 10 pointers to integersf)int (*a)[10];// A pointer to an arrayof 10 integersg) int (*a)(int);// A pointer to a function a that takes an integerargumentand returns an integer h) int (*a[10])(int);// An array of 10 pointers to functions that take aninteger argument and returnan integer
3.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
4.写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。
#define MIN( A,B) ((A)<= (B)?(A) : (B)) A <= B?A : B
5.关键字static的作用是什么?
在C语言中,关键字static有三个明显的作用:
1).在函数体,一个被声明为静态的全局变量在这一函数被调用过程中维持其值不变。 (值的保存)
2).在模块内(但在函数体外),一个被声明为静态的全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。(限制作用域)
3).在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。(限制作用域)
6.关键字const是什么含意?下面的声明都是什么意思?
1 const int a;2 int const a; 3 const int *a; 4 int const * a; 5 int * const a; 6 int const * const a;
1、const int a;
2、int const a;
3、 4、内容不可变,指针可变 :constint *a;
5、内容不可变,指针可变 :int * const a;
6、内容可变,指针不可变: intconst *const a;
8.关键字volatile有什么含意并给出三个不同的例子。
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。
精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
下面是volatile变量的几个例子:
1).并行设备的硬件寄存器(如:状态寄存器)
2).一个中断服务子程序中会访问到的非自动变量(Non-automaticvariables)
3).多线程应用中被几个任务共享的变量
6.int (*s[10])(int)表示的是什么啊
int (*s[10])(int)函数指针数组,每个指针指向一个int func(int param)的函数。
1.有以下表达式:
inta=248; b=4;int const c=21;const int *d=&a;
int*const e=&b;intconstint*constf =&a;
请问下列表达式哪些会被编译器禁止?为什么?
*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;
答:*c这是个什么东东,禁止
d=&b是很OK
e=34不OK
2.交换两个变量的值,不使用第三个变量。即a=3,b=5,交换之后a=5,b=3;
答:有两种解法, 一种用算术算法, 一种用^(异或)
a = a + b;
b = a - b;
a = a - b;
or
a =a^b;//只能对int,char..
b = a^b;
a = a^b;
2个bit (bit1与bit2异或,结果为0说明它们不同,则bit2异或0可把bit1还原。
结果为1说明它们相同,则bit2异或1可把bit1还原。
4.#include
#include
voidgetmemory(char*p)//函数的参数是局部变量,在这里给它分配内存还在,但是P释放了。
{
p=(char *) malloc(100);
}
intmain( )
{
char *str=NULL;
getmemory(str);
strcpy(str,"helloworld");
printf("%s/n",str);
free(str);
return 0;
}
答:程序崩溃,getmemory中的malloc不能返回动态内存, free()对str操作很危险
解决方案1:可改为按引用传递:void getmemory(char *&p)
解决方案2:返回指针
Char* getmemory(char *p)
{
p=(char *) malloc(100);
return p;
}
5.charszstr[10];
strcpy(szstr,"0123456789");
产生什么结果?为什么?
答;正常输出,长度不一样,会造成非法的OS,覆盖别的内容.‘\0’没保存
2.c指针
int *p[n];-----指针数组,每个元素均为指向整型数据的指针。
int (*p)[n];------p为指向一维数组的指针,这个一维数组有n个整型数据。
int *p();----------函数带返回指针,指针指向返回的值。
int (*p)();------p为指向函数的指针。
3.数组越界问题 (这个题目还是有点小险的)
下面这个程序执行后会有什么错误或者效果:
#defineMAX 255
intmain()
{
unsignedchar A[MAX],i;
for (i=0;i<=MAX;i++)
A[i]=i;
}
解答:MAX=255,数组A的下标范围为:0..MAX-1,这是其一,其二 当i循环到255时,循环内执行: A[255]=255;这句本身没有问题,但是返回for (i=0;i<=MAX;i++)语句时,由于unsignedchar的取值范围在(0..255),i++以后i又为0了..无限循环下去.
注:char类型为一个字节,取值范围是[-128,127],unsignedchar [0 ,255]
4.C++:memset ,memcpy和strcpy 的根本区别?
答:#include "memory.h"
memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为' '或'';例:char a[100];memset(a, '', sizeof(a));
void main()
{
char a[100];
memset(a, 'a',sizeof(a)-1);
memset(&a[99],'\0',1);
printf("%s\n",a);
charstr1[100]="abc";
charstr2[50]="efghdfkdjf";
memcpy(str1,str2, sizeof(str2));
printf("%s\n",str1);
strcpy(str1, str2);
printf("%s\n",str1);
}
strcpy原型:
char *strcpy_su(char *dest,char *src)
{
assert((dest!=NULL)&&(src!=NULL));
char *address = dest;
while((*dest++=*src++)!='\0')
continue;
return address;
}
用法:#include
功能:把src所指由NULL结束的字符串复制到dest所指的数组中。
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
memcpy原型:
void *memcpy_su(void *dest, void *src, unsigned int count)
{
assert((dest!=NULL)&&(src!=NULL));
char*bdest = (char*)dest;
char* bsrc =(char*) src;
while(count-->0)
*bdest++ = *bsrc++;
return dest;
}
用法:#include
功能:由src所指内存区域复制count个字节到dest所指内存区域。
说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。
Memset原型:
原型:extern void *memset(void *buffer, char c, intcount);
用法:#include
功能:把buffer所指内存区域的前count个字节设置成字符c。
说明:返回指向buffer的指针。
void *memset_su(void*buffer, int c, int count)
{
assert ((buffer!=NULL));
char* buffer2 =(char*)buffer;
while(count-->0)
*buffer2++ = c;
return buffer;
}
5.ASSERT()是干什么用的
答:ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常用来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。例如,变量n在程序中不应该为0,如果为0可能导致错误,你可以这样写程序:
......
ASSERT( n != 0);
k = 10/ n;
......
ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略。
assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。
#include
#include
void main()
{
intn=1;
assert( n !=0); //c c++中使用
//ASSERT( n != 0);//什么头文件?
printf("su\n");
}