C语言面试题(带答案)三

2019-03-28 10:16|来源: 网络

1.有以下表达式:

int a=248; b=4;int const c=21;const int *d=&a;

int *const e=&b;int constint  *const f =&a;

请问下列表达式哪些会被编译器禁止?为什么?

*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;

答:*c 这是个什么东东,禁止

d=&b是很OK

e=34 不OK

e = &a 说了是const 禁止  e的地址不能改

const int  *const f =&a; 禁止f的内容和地址都不能改

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;


2bit (bit1bit2异或,结果为0说明它们不同,则bit2异或0可把bit1还原。

结果为1说明它们相同,则bit2异或1可把bit1还原。


3. 数组越界问题 (这个题目还是有点小险的)

下面这个程序执行后会有什么错误或者效果:

#define MAX 255

int main()

{

unsigned char 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++)语句时,由于unsigned char的取值范围在(0..255),i++以后i又为0了..无限循环下去.

注:char类型为一个字节,取值范围是[-128,127],unsigned char [0 ,255]

4. C++:memset ,memcpy 和strcpy 的根本区别?

答:#include "memory.h"

memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为' '或'';例:char a[100];memset(a, '', sizeof(a));

memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。

strcpy就只能拷贝字符串了,它遇到'\0'就结束拷贝;例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个'\0'之前)是否超过50位,如超过,则会造成b的内存地址溢出。

void main()

{

char a[100];

memset(a, 'a', sizeof(a)-1);

   memset(&a[99], '\0',1);

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

char str1[100]="abc";

char str2[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 <string.h>

功能:把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 <memory.h>

功能:由src所指内存区域复制count个字节到dest所指内存区域。

说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。

Memset原型:

原型:extern void *memset(void *buffer, char c, int count);

用法:#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 <stdio.h>

#include <assert.h>

void main()

{  

int n=1;

assert( n != 0);    //c c++中使用

//ASSERT( n != 0); //什么头文件?

printf("su\n");

}


6.请问以下代码有什么问题:

1).

int main()

{

char a;

char *str=&a;

strcpy(str,"hello");

printf(str);

return 0;

}

答;没有为str分配内存空间,将会发生异常

问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。


7. 冒泡排序:

#include "stdio.h"

void printArr(int R[],int n)

{  

int i;

for(i=0;i<n;i++)

printf("%d  ",R[i]);

printf("\n");

}

void swap(int * a ,int * b)

{

int c=*a;

*a=*b;

*b=c;

}

//4 冒泡排序

void maopaoSort(int R[],int n)

{

for(int i=0;i<n-1;i++)  // 需要冒泡的次数

{  /*

for(int j=0;j<n-1-i;j++)   // // 每次需要比较的次数

{

if(R[j]>R[j+1])      //大的往下沉

{

swap(&R[j],&R[j+1]);

}

}

*/

     for(int j=n-1;j>i;j--)   // // 每次需要比较的次数

{

if(R[j]<R[j-1])      //小的往上冒

{

swap(&R[j],&R[j-1]);

}

}

}

}

void main()

{  

int i;

int num[6]={0};

printf("Please input 6 numbers:\n");

for(i=0;i<6;i++)

scanf("%d",&num[i]);

puts("before sort:");

printArr(num,6);

   maopaoSort(num,6);

puts("after sort:");

printArr(num,6);

}


试题8:再看看下面的一段程序有什么错误:

swap( int* p1,int* p2 )

{

int *p;  

*p = *p1;

*p1 = *p2;

*p2 = *p;

}

在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“Access Violation”。该程序应该改为:

swap( int* p1,int* p2 )

{

int p;

p = *p1;

*p1 = *p2;

*p2 = p;

}


9.对1,2,3, 4, 5 这五个数任意取出两个数,列出他们的所有组合。

void main()

{  

char a[]={'1','2','3','4','5'};

for(int i=0;i<5-1;i++)

{

for(int j=i+1;j<5;j++)

if(a[i]!=a[j])

{

cout<<a[i]<<a[j]<<"  ";

cout<<a[j]<<a[i]<<"  ";

}

cout<<endl;

}

}

//12 21 13 31 14 41 15 51

//23 32 24 42 25 52

//34 43 35 53

//45 54

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

#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL

1) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)

2)懂得预处理器将为你计算常数表达式的值,因此,直接写出你是怎么样计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。

3) 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。

4) 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。

1). 一个参数既可以是const还可以是volatile吗?解释为什么。

2). 一个指针可以是volatile 吗?解释为什么。

3). 下面的函数有什么错误:

int square(volatile int *ptr)

{

return (*ptr) * (*ptr);

}

下面是答案

1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。

2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,

编译器将产生类似下面的代码:

int square(volatile int *ptr)

{

int a,b;

a = *ptr;

b = *ptr;

return a * b;

}

由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

long square(volatile int *ptr)

{

int a;

a = *ptr;

return a * a;

}


书生整理于网络


相关问答

更多
  • java基础面试题[2022-04-05]

      1.抽象:   抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。   2.继承:   继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继 承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变 ...
  • 你这问题问得没水平了。。。找这类考试试题,你到书店转转,随便就能抓一大把,你挑本感觉最好的买下就可以了啊,不花几个钱。
  • 每个公司的面试题肯定都不一样啊 就是一个公司不同的考官,题也不一样啊
  • 某大公司的PHP面试题 管理提醒: 本帖被 haowubai 执行取消置顶操作(2009-07-30) 1. 如何用php的环境变量得到一个网页地址的内容?ip地址又要怎样得到? [php] echo $_SERVER ['PHP_SELF']; echo $_SERVER ['SERVER_ADDR']; [/php] 2. 求两个日期的差数,例如2007-2-5 ~ 2007-3-6 的日期差数 [php] $begin=strtotime('2007-2-5'); $end=strtotime('20 ...
  • 各地不同
  • java基础面试题[2023-10-31]

    1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继 承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修 ...
  • 一、请填写BOOL , float, 指针变量 与“零值”比较的 if 语句。(10分) 提示:这里“零值”可以是0, 0.0 , FALSE或者“空指针”。例如 int 变量 n 与“零值”比较的 if 语句为: if ( n == 0 ) if ( n != 0 ) 以此类推。 请写出 BOOL flag 与“零值”比较的 if 语句: 请写出 float x 与“零值”比较的 if 语句: 请写出 char *p 与“零值”比较的 if 语句: 二、以下为Wi ...
  • 面试题及答案[2022-04-05]

    要归还,改善环境。比如。煤炭要涨价,同时也应该积极主动地去影响环境。 2 专业问题,不会,同事丢失的物品不知怎么出现在我的抽屉里了,是不是有人在开我的玩笑,这样会造成误会的,由领导处理1 环境是人组成的,所以不是不可改变,多给身边的人一个微笑,大家的心情就可能好一点,自己环境也会变得更加团结友善。把物品交给领导? 3 向领导汇报。人要做出改变以适应环境
  • 我有一部分!
  • 基本就是些这 给你题库: 1. What letter is a body of water? 2. What is it that found in the every center of America and Australia? 3. Why is a river rich? 4. Which letter is very useful to a deaf woman? 5. Which runs faster, heat or cold? Why? 6.下面是一道经典的英语填空题,注意,所有空格均 ...