C语言笔试题答案

更新时间:2024-06-18 19:19:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

C语言笔试题答案

一、 简答题

1. 程序的局部变量存在于(栈)中,全局变量存在于(静态区)中,动态申请数据存在于

(堆)中。 2. 设有以下说明和定义:

typedef union {long i; int k[5]; char c;} DATE; struct data { int cat; DATE cow; double dog;} too; DATE max;

则语句 printf(\的执行结果是:_______

data是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20。

data是一个struct, 每个变量分开占用空间. 依次为int4 + DATE20 + double8 = 32.所以结果是 20 + 32 = 52。

3. 32位系统下,请问如下语句的值

unsigned char *p1; unsigned long *p2;

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

4. int i=10, j=10, k=3; k*=i+j; k最后的值是?

答:60,此题考察优先级,实际写成: k*=(i+j);,赋值运算符优先级最低 5. #define DOUBLE(x) x+x ,i = 5*DOUBLE(5); i 是多少?

答案:i 为30。

6. 下面程序的输出是_____,为什么? char *ptr;

if ((ptr = (char *)malloc(0)) == NULL) {

puts(\} else {

puts(\}

答:Got a valid pointe

7. 以下程序运行后的输出结果是______ 。

main()

{

char m;

m='B'+32; printf(\}

答:b

8. 已有定义如下:

struct node {

int data;

struct node *next; } *p;

以下语句调用malloc函数,使指针p指向一个具有struct node类型的动态存储空间。请填空p = (struct node *)malloc(________); 答:sizeof(struct node)

9. 在绝对地址0xXXXXXXXX上写入字符’a’的语句是___________。

答:unsigned char *p = (unsigned char *)0xF000FF00; *p = ‘a’;

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

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

2)懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。 3) 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。

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

11. 写一个\标准\宏MIN ,这个宏输入两个参数并返回较小的一个。

#define MIN(A,B) ((A) <= (B) ? (A) : (B))

1)标识#define在宏中应用的基本知识。这是很重要的。因为在嵌入(inline)操作符 变为标准C的一部分之前,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。

2)三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个用法是很重要的。

3)懂得在宏中小心地把参数用括号括起来,因为#define仅仅做替换,如果我们写 #define MUL(a,b) a/b 的话,那么我写MUL(a+1,b-1)替换之后的表达式就为a+1/b-1,这个结果显然是违背我们定义的目的的。

12. 嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环呢? 这个问题用几个解决方案。 while(1){}或者for(;;){} 13. 用变量a给出下面的定义

a) 一个整型数(An integer)

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

an intege)

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

integers)

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

g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a

function that takes an integer as an argument and returns an integer)

h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一

个整型数( An array of ten pointers to functions that take an integer argument and return an integer ) 答案是:

a) int a; // 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 integers f) int (*a)[10]; // A pointer to an array of 10 integers

g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer

h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer

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

全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。

static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件。

static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;

static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;

static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。 15. 关键字const的含义。

声明一个只读变量,可用于修饰指针,变量,形参等等 const int a;修饰变量 int const a;修饰变量

const int *a;修饰指针的指向,表示不希望通过指针改变指向的这个空间的值

int * const a;修饰指针变量,表示不希望改变指针变量p的值,也就是指针的指向

const int const * a ;表示不希望通过指针改变指针指向的这个空间存储的值也不希望改变指针的指向。

16. 关键字volatile有什么含意?并给出三个不同的例子。

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

1) 并行设备的硬件寄存器(如:状态寄存器)

2)一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3)多线程应用中被几个任务共享的变量

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

是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。 18. 一个指针可以是volatile 吗?解释为什么。

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

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

int square(volatile int *ptr) {

return *ptr * *ptr; }

这段代码有点变态。这段代码的目的是用来返指针*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;

}

20. 在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个

纯粹的ANSI编译器。写代码去完成这一任务。

答:

int *ptr;

ptr = (int *)0x67a9; *ptr = 0xaa55;

21. 局部变量能否和全局变量重名?

答:能,局部会屏蔽全局。要用全局变量,需要使用\。局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。 22. 如何引用一个已经定义过的全局变量?

答:extern

可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。

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

答:可以,在不同的C文件中以static形式来声明同名全局变量。可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。

24. 语句for( ;1 ;)有什么问题?它是什么意思? 答:和while(1)相同,死循环。

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

答:前一个循环一遍再判断,后一个判断以后再循环。 26. 下列哪种方法更好,为什么?

define dPS struct s * typedef struct s * tPS;

以上两种情况的意图都是要定义dPS 和 tPS 作为一个指向结构s指针。哪种方法更好呢?(如果有的话)为什么?

这是一个非常微妙的问题,任何人答对这个问题(正当的原因)是应当被恭喜的。答案是:typedef更好。思考下面的例子: dPS p1,p2; tPS p3,p4; 第一个扩展为 struct s * p1, p2;

上面的代码定义p1为一个指向结构的指,p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。 27. 下面的结构是合法的吗,如果是它做些什么?

}

printf(\}

int main() {

fun(10); return 0; }

答:0,1,2,5,10 析:递归展开

三、 编程题

1. 不调用库函数,自己实现memcpy函数。

typedef int size_tt;

void *memcpy(void *dest,const void *src,size_tt count)//源串要有const修饰 {

char *pDest=(char*)(dest);//将原始指针赋给新变量 const char *pSrc=(const char*)(src); //判断传参是否合法 if(NULL == dest || NULL == src) { return NULL; }

//目的地址和源地址重叠,从源地址的末尾方向开始拷贝 if( pDest > pSrc && pDest < pSrc+count) {

//将指针指向末尾

pDest = pDest + count-1; pSrc = pSrc + count-1; while(count--) {

*pDest--=*pSrc--; } }

//目的地址和源地址不重叠,从源地址的开始方向拷贝 else {

while(count--) {

*pDest++=*pSrc++; }

}

return pDest;//返回,这样可以嵌套使用 }

2. 不调用库函数,自己实现strcpy函数 。

int Strcmp(const char *str1, const char *str2) { assert(str1 && srt2); while(*str1 && *str2 && (*str1 == *str2)) {

str1++; str2++; }

return (*str1 - *str2); }

3.

a) 编写strcat函数,已知strcat函数的原型是char *strcat (char *strDest, const char

*strSrc);其中strDest 是目的字符串,strSrc 是源字符串(不能调用库函数)。

#include

char *strcat (char * dst, const char * src) { if(NULL == dst || NULL == src) { return NULL; } char * cp = dst; while( *cp ) cp++; /* find end of dst */ while( *cp++ = *src++ ) ; /* Copy src to end of dst */ return dst; /* return dst */ }

int main() { char str1[100] = \ char str2[] = \ printf(\ return 0; }

b) strcat能把strSrc 的内容连接到strDest,为什么还要char * 类型的返回值?

答:方便赋值给其他变量

4. 两个字符串,s,t;把t字符串插入到s字符串中,s字符串有足够的空间存放t字符串。

char *insert(char *t, const char *s) { char *q = t; const char *p =s; if(NULL == q) return NULL; while(*p != '\\0') { p++; } while(*q != 0) { *p = *q; p++; q++; } *p = '\\0'; return t; } 5. 写一函数,实现删除字符串str1中含有的字符串str2。

#include

char *delstr(char *src,const char *sub) { char *st = src,*s1 = NULL; const char *s2 = NULL; while (*st && *sub) { s1 = st; s2 = sub; while (*s1 && *s2 && !(*s1 - *s2) ) { s1++; s2++; } if (!*s2) { while (*st++ = *s1++); st = src; } st++;

} return (src); }

int main() { char str1[] = \ char str2[] = \ printf(\ return 0; }

6. 编程,判断存储方式是大端存储,还是小端存储,并说出为什么要进行大小端的判定?

int check_little_endian() { union{ int a; char b; }c; c.a=1; return (c.b == 1); }

int check_little_endian() { int i = 0x00000001; char *p = &a; return *P; }

static union {

charc[4];

unsigned long l; }endian_test = {{'l','?','?','b'}};

#define ENDIANNESS((char)endian_test.l)

7. 不调用库函数,自己实现long atol(const char *nptr)函数。

long __cdecl atol( const char *nptr ) /*1.const修饰*/ { int c; /* current char */ long total; /* current total */

int sign; /* if ''-'', then negative, otherwise positive */ /* skip whitespace */

/*char ,signed char 、unsigned char 类型的数据具有相同的特性然而当你把一个单字节的数赋给一个整型数时,便会看到它们在符号扩展上的差异。*/

/*ascii码当赋给整形数时要转为unsigned char再转为int */ while ( isspace((int)(unsigned char)*nptr) ) /*2.去掉首部的空格*/ ++nptr;

c = (int)(unsigned char)*nptr++; /*取得第一个非空格的字符*/ sign = c; /* save sign indication */

if (c == '-' || c == '+') /*如果第一个非空格字符为符号*/ c = (int)(unsigned char)*nptr++; /* skip sign */ /*跳过符号,将符号后的那个字符给c*/

total = 0; /*结果置为0*/ while (isdigit(c)) { /*3.如果碰到非法字符则停止*/ total = 10 * total + (c - '0'); /* accumulate digit */ c = (int)(unsigned char)*nptr++; /* get next char */ } if (sign == '-') return -total; else return total; /* return result, negated if necessary */ }

8. 编写strcat函数()。已知strcat函数的原型是char *strcat (char *strDest, const char *strSrc);

其中strDest 是目的字符串,strSrc 是源字符串。

a) 不调用C++/C 的字符串库函数,请编写函数 strcat。

char * __cdecl strcat (char * dst, const char * src) { insert(dest != NULL && src != NULL); char * cp = dst; while( *cp ) cp++; /* find end of dst */ while( *cp++ = *src++ ) ; /* Copy src to end of dst */ return( dst ); /* return dst */ }

b) strcat能把strSrc 的内容连接到strDest,为什么还要char * 类型的返回值?

答:方便赋值给其他变量

9. 写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)。功能:在字符串

中找出连续最长的数字串,并把这个串的长度返回,并把这个最长数字串付给其中一个函数参数outputstr所指内存。例如:\的首地址传给intputstr后,函数将返回9,outputstr所指的值为123456789

int continumax(char *outputstr, char *inputstr) {

char *in = inputstr, *out = outputstr, *temp, *final; int count = 0, maxlen = 0; while( *in != '\\0' ) {

if( *in > 47 && *in < 58 ) {

for(temp = in; *in > 47 && *in < 58 ; in++ ) count++; } else

in++;

if( maxlen < count ) {

maxlen = count; count = 0; final = temp; } }

for(int i = 0; i < maxlen; i++) {

*out = *final; out++; final++; }

*out = '\\0'; return maxlen; }

10. 不用库函数,用C语言实现将一整型数字转化为字符串。

int getlen(char *s) {

int n;

for(n = 0; *s != '\\0'; s++) n++; return n; }

void reverse(char s[]) {

int c,i,j;

for(i = 0,j = getlen(s) - 1; i < j; i++,j--) {

c = s[i]; s[i] = s[j]; s[j] = c; } }

void itoa(int n,char s[]) {

int i,sign;

if((sign = n) < 0) n = -n; i = 0;

do{/*以反序生成数字*/

s[i++] = n + '0';/*get next number*/ }while((n /= 10) > 0);/*delete the number*/ if(sign < 0) s[i++] = '-'; s[i] = '\\0'; reverse(s); }

#include using namespace std;

void itochar(int num); void itochar(int num) {

int i = 0; int j ;

char stra[10]; char strb[10]; while ( num ) {

stra[i++]=num+48; num=num/10; }

stra[i] = '\\0'; for( j=0; j < i; j++) {

strb[j] = stra[i-j-1]; }

strb[j] = '\\0'; cout >> strb;

}

int main() {

int num; cin>>num; itochar(num); return 0; }

11. 用指针的方法,将字符串“ABCD1234efgh”前后对调显示。

#include #include #include

int main() { char str[] = \ int length = strlen(str); char * p1 = str; char * p2 = str + length - 1; while(p1 < p2) { char c = *p1; *p1 = *p2; *p2 = c; ++p1; --p2; } printf(\// system(\ return 0; }

12. 有一分数序列:1/2,1/4,1/6,1/8??,用函数调用的方法,求此数列前20项的和。

#include

double getValue() { double result = 0; int i = 2; while(i < 42) { result += 1.0 / i;/*一定要使用1.0做除数,不能用1,否则结果将自动转化成整数,即0.000000*/

i += 2; }

return result; }

int main() { printf(\ system(\ return 0; }

13. 实现子串定位。

char * mystrstr(char* MainStr, const char* SubStr) { const char *q; char * tmp = MainStr,*p;

assert((MainStr!=NULL)&&( SubStr!=NULL));//用断言对输入进行判断

while(*tmp++) //内部进行递增 { p = tmp; q = SubStr; while(*q && *p && *p++ == *q++); if(!*q ) {

return tmp;/* MainStr指向当前起始位*/ } } return NULL; }

int main() { char str[30] = \ char substr[10] = \ char *p = NULL; if(NULL == ( p = mystrstr(str,substr) ) ) { printf(\ } else { printf(\ } return 0;

}

14. 有1,2,....一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复

杂度O。

#include

void sort(int *arr,int len) { int temp,i = 0; for(int i = 0; i < len; ) { temp = arr[arr[i] - 1]; arr[arr[i] - 1] = arr[i]; arr[i] = temp; if ( arr[i] == i + 1) i++; } }

int main() { int a[] = {10,6,9,5,2,8,4,7,1,3}; int len = sizeof(a) / sizeof(int); int temp; sort(a,len); for (int j = 0; j < len; j++) { printf(\ if(!(++j % 5)) { putchar('\\n'); } } putchar('\\n'); return 0; }

15. 编写一个C函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由

同一字符组成的。

char * search(char *cpSource, char ch) { char *cpTemp=NULL, *cpDest=NULL; int iTemp, iCount=0; while(*cpSource)

}

{ if(*cpSource == ch) { iTemp = 0; cpTemp = cpSource; while(*cpSource == ch) ++iTemp, ++cpSource; if(iTemp > iCount) iCount = iTemp, cpDest = cpTemp; if(!*cpSource) break; } ++cpSource; }

return cpDest;

16. 给定字符串A和B,输出A和B中的最大公共子串。

#include #include #include

char *commanstring(char shortstring[], char longstring[]) { int i, j; char *substring=malloc(256); if(strstr(longstring, shortstring)!=NULL) //如果??,那么返回shortstring return shortstring; for(i=strlen(shortstring)-1;i>0; i--) //否则,开始循环计算 { for(j=0; j<=strlen(shortstring)-i; j++){ memcpy(substring, &shortstring[j], i); substring[i]='\\0'; if(strstr(longstring, substring)!=NULL) return substring; } } return NULL; }

int main() { char *str1=malloc(256); char *str2=malloc(256); char *comman=NULL;

}

gets(str1); gets(str2);

if(strlen(str1)>strlen(str2)) //将短的字符串放前面 comman=commanstring(str2, str1); else comman=commanstring(str1, str2);

printf(\return 0;

17. 编程实现:把十进制数(long型)分别以二进制和十六进制形式输出,不能使用printf系

列库函数。

include #include #include

#define SIZE 32

char *dec_bin(long num) { int i = SIZE; char *buffer = (char *) malloc(SIZE+1); if(NULL == buffer) { printf(\ return NULL; } buffer[SIZE] = '\\0'; memset(buffer,'0',SIZE); while(num) { buffer[i--] = num % 2 + '0'; num = num / 2; } return buffer; }

char *dec_hex(long num) { int i ; char *buffer = (char*)malloc(11); if(NULL == buffer) { printf(\

return NULL; } buffer[0] = '0'; buffer[1] = 'x'; buffer[10] = '\\0'; char* temp = buffer + 2; for ( i = 0; i < 8; i++) { temp[i] = (char)(num<<4*i>>28); temp[i] = temp[i] >= 0 ? temp[i] : temp[i] + 16; temp[i] = temp[i] < 10 ? temp[i] + 48 : temp[i] + 55; } return buffer; }

int main() { long int num = 20; printf(\ //dec_bin(num); printf(\ return 0; }

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

#include void main() {

int i=60; int j=50;

/*方法一*/ i=i+j; j=i-j; i=i-j;

printf(\ printf(\}

方法二: i^=j; j^=i; i^=j;

方法三:

// 用加减实现,而且不会溢出

a = a+b-(b=a);

19. 写一个程序,把一个100以内的自然数分解因数。(自然数分解因数就是将一个自然数

分解为几个素数的乘积,提示,由于该数不是很大,所以可以将质数保存在数组中,以加快计算速度)。

①递归算法: {

#include #include

int resolve(unsigned int num) { int i; char buf[10] = {0}; for(i = 2;i <= sqrt(num);i++) { if(0 == num % i ) { printf(\ return resolve(num /= i); break; } } return printf(\}

int main() { unsigned int num; while(scanf(\ resolve(num); return 0; }

②数组

#include #include #include

int resolve(unsigned int number) { int i = 2,num = number; int j = 0; char buf[30] = {0}; while(i <= sqrt(num))

{ if(0 == num % i) { buf[j++] = i + '0'; buf[j++] = '*'; num /= i; continue; } else { i++; } } buf[j+2] = '\\0';

// buf[j++] = num + '0'; 如果num大于9将会出错 char tmp[3] = {'0'};/*100以内最大地质数最多两位*/ sprintf(tmp,\ strcat(buf,tmp); if(0 == j) { printf(\ } else { printf(\ } return 0; }

int main() { unsigned int num; printf(\ while(scanf(\ resolve(num); return 0; }

20. 完成字符串拷贝可以使用sprintf、strcpy及memcpy函数,请问这些函数有什么区别,

你喜欢使用哪个,为什么?

sprintf 可以进行额外的格式化

strcpy 会复制直到出现 '' 为止,可能溢出

memcpy 只负责复制指定数量的 bytes,不处理 '' 的情况

这些函数的区别在于 实现功能 以及 操作对象 不同。

strcpy 函数操作的对象是 字符串,完成 从 源字符串 到 目的字符串 的 拷贝 功能。

snprintf 函数操作的对象 不限于字符串:虽然目的对象是字符串,但是源对象可以是字符串、也可以是任意基本类型的数据。

这个函数主要用来实现 (字符串或基本数据类型)向 字符串 的转换 功能。如果源对象是字符串,并且指定 %s 格式符,也

可实现字符串拷贝功能。 memcpy 函数顾名思义就是 内存拷贝,实现 将一个 内存块 的内容复制到另一个 内存块 这一功能。内存块由其首地址以及长度确定。

程序中出现的实体对象,不论是什么类型,其最终表现就是在内存中占据一席之地(一个内存区间或块)。因此,memcpy 的操作

对象不局限于某一类数据类型,或者说可 适用于任意数据类型,只要能给出对象的起始地址和内存长度信息、并且对象具有可操作性即可。

鉴于 memcpy 函数等长拷贝的特点以及数据类型代表的物理意义,memcpy 函数通常限于同种类型数据或对象之间的拷贝,

其中当然也包括字符串拷贝以及基本数据类型的拷贝。 对于字符串拷贝来说,用上述三个函数都可以实现,但是其实现的效率和使用的方便程度不同:

? strcpy 无疑是最合适的选择:效率高且调用方便。

? snprintf 要额外指定格式符并且进行格式转化,麻烦且效率不高。

? memcpy 虽然高效,但是需要额外提供拷贝的内存长度这一参数,易错且使用不便;并且如果长度指定过大的话

? (最优长度是源字符串长度 + 1),还会带来性能的下降。其实 strcpy 函数一般是在内部调用 memcpy 函数或者

? 用汇编直接实现的,以达到高效的目的。因此,使用 memcpy 和 strcpy 拷贝字符串在性能上应该没有什么大的差别。

对于非字符串类型的数据的复制来说,strcpy 和 snprintf 一般就无能为力了,可是对 memcpy 却没有什么影响。但是,

对于基本数据类型来说,尽管可以用 memcpy 进行拷贝,由于有赋值运算符可以方便且高效地进行同种或兼容类型的数据之间的拷贝,

所以这种情况下memcpy几乎不被使用。memcpy的长处是用来实现(通常是内部实现居多)对结构或者数组的拷贝,其目的是或者高效,或者使用方便,甚或两者兼有。 21. 输出和为一个给定整数的所有组合。例如n=5,5=1+4;5=2+3(相加的数不能重复)则

输出1,4;2,3。

#include

int main(void)

{ }

unsigned long int i,j,k;

printf(\scanf(\if( i % 2 == 0) j = i / 2; else j = i / 2 + 1; printf(\for(k = 0; k < j; k++) printf(\return 0;

22. 读文件file1.txt的内容(例如):

12 34 56

输出到file2.txt: 56 34 12

(逆序)

#include #include

void test(FILE *fread, FILE *fwrite) {

char buf[1024] = {0};

if (!fgets(buf, sizeof(buf), fread)) return; test( fread, fwrite ); fputs(buf, fwrite); }

int main(int argc, char *argv[]) {

FILE *fr = NULL; FILE *fw = NULL;

fr = fopen(\ if(NULL == fr) { perror(\

exit(-1); }

fw = fopen(\ if(NULL == fw) { perror(\ exit(-2); }

test(fr, fw); fclose(fr); fclose(fw); return 0; }

23. 有一个数组a[1000]存放0--1000;要求每隔二个数删掉一个数,到末尾时循环至开头继续

进行,求最后一个被删掉的数的原始下标位置。以7个数为例:{0,1,2,3,4,5,6,7} 0-->1-->2(删除)-->3-->4-->5(删除)-->6-->7-->0(删除),如此循环直到最后一个数被删除。

24. 写一个函数,将其中的'\\t'都转换成4个空格。

int change(char* pstr) { if(NULL == pstr) { return -1; } while(*pstr++ != '\\0') { if (*pstr == '\\t') { } } return 0; }

25. 编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”

如果n=2,移位后应该是“hiabcdefgh”。函数头是这样的: //pStr是指向以'\\0'结尾的字符串的指针 //steps是要求移动的n

void LoopMove ( char * pStr, int steps ) {

//请填充...

}

void LoopMove ( char *pStr, int steps ) {

int n = strlen( pStr ) - steps; char tmp[MAX_LEN]; strcpy ( tmp, pStr + n ); strcpy ( tmp + steps, pStr); *( tmp + strlen ( pStr ) ) = '\\0'; strcpy( pStr, tmp ); }

26. 判断两个数组中是否存在相同的数字,给定两个排好序的数组,怎样高效得判断这两个

数组中存在相同的数字?

bool findcommon2(int a[], int size1, int b[], int size2) {

int i=0,j=0;

while(ib[j]) j++; if(a[i]

return false; } 27. 按单词反转字符串并不是简单的字符串反转,而是按给定字符串里的单词将字符串倒转

过来,就是说字符串里面的单词还是保持原来的顺序,这里的每个单词用空格分开。例如:Here is www.fishksy.com.cn经过反转后变为:www.fishksy.com.cn is Here

char* reverse_word(const char* str) {

int len = strlen(str);

char* restr = new char[len+1]; strcpy(restr,str); int i,j;

for(i=0,j=len-1;i

int k=0; while(k

{ i=j=k; while(restr[j]!=' ' && restr[j]!='' ){ j++; } k=j+1; j--; for(;i

return restr; }

28. 求一个整形中1的位数。

①int NumberOf1_Solution1(int i) {

int count = 0; while(i) {

if(i & 1)

count ++;

i = i >> 1; }

return count; }

②int NumberOf1_Solution2(int i) {

int count = 0;

unsigned int flag = 1; while(flag) {

if(i & flag)

count ++;

flag = flag << 1; }

return count; }

③int NumberOf1_Solution3(int i) {

int count = 0;

while (i) {

++ count; i = (i - 1) & i; }

return count; }

29. 费波那其数列,1,1,2,3,5??编写程序求第十项。可以用递归,也可以用其他方

法,但要说明你选择的理由。

int main() { printf(\ printf(\ return 0; }

/* 递归算法 */ int Pheponatch(int N) { if( N == 1 || N == 2) { return 1; } else return Pheponatch( N -1 ) + Pheponatch( N -2 ); }

/* 非递归算法 */ int Pheponatch2(int N) { int x = 1, y = 1, temp; int i = 2; while(1) { temp = y; y = x + y; x = temp; i++;

}

if( i == N ) break; } return y;

本文来源:https://www.bwwdw.com/article/iqq3.html

Top