1.请写出 bool flag 与“零值”比较的 if 语句

if(flag)
if(!flag)

2.请写出 float x 与“零值”比较的 if 语句

const float ESPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON))

3.请写出 char *p 与“零值”比较的 if 语句

if(p == NULL)
if(p != NULL)

4.以下为 Linux下的 32 位 C程序,请计算 sizeof 的值。

char str[] = “Hello” ;

char *p = str ;

int n = 10;

请计算 (1)sizeof (str ) = (2)sizeof ( p ) = (3)sizeof ( n )

(1) 6 数组求大小,连同字符后的\0也加上,并且*类型1*6=6
(2) 4 指针类型,在32位操作系统中指针类型大小位4,64位大小是8 
(3) 4 指针类型,在32位操作系统中指针类型大小位4,64位大小是8

4.

void Func ( char str[100]) 
{ 

…… ; 

}


请计算 sizeof( str ) = 4

str为数组,数组传参传的数组名也为地址,地址的大小和指针大小一致 4

5.

void *p = malloc( 100 );

请计算sizeof ( p ) = 4

6.

e) 一个有10个指针的数组,该指针是指向一个整型数的;  int *a[10];

f) 一个指向有10个整型数数组的指针 ;  int (*a)[10];

g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数;   int(*a)(int);

h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数;int(*a[10])(int);

7.设有以下说明和定义:


typedef union 
{
  long i; 
  int k[5];
  char c;
} DATE;

struct data 
{ 
  int cat;
   DATE cow;
   double dog;
} too;

DATE max;

则语句 printf("%d",sizeof(too)+sizeof(max));的执行结果是:52

8.请问以下代码有什么问题

int main()
{
  char a;
  char *str=&a;
  strcpy(str,"hello");
  printf(str);
  return 0;
}

指针str没有分配内存空间,将会发生异常问题出在将一个字符串复制进一个字符变量指针所指 地址。虽然可以正确输出结果,但因为越界进行内在 读写而导致程序崩溃。

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

char* s="AAA";
printf("%s",s);
s[0]='B';
printf("%s",s);
修改后
char str[] = "AAA";
char* s = str;

①"AAA"是字符串常量,s是指针,指向这个字符串常量。

②数组内成员不能直接赋值

10.int (*s[10])(int) 表示的是什么啊

函数指针数组,每个指针指向一个int func(int param)的函数。

11.c和c++中的struct有什么不同

c和c++中struct的主要区别是c中的struct不可以含有成员函数,而c++中的struct可以。

c++中 struct和class的主要区别在于默认的存取权限不同, struct默认为public,而class默认为privat

12.

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;
}会出现什么问题?

程序崩溃,getmemory中的malloc 没有返回动态内存p, free()对str操作很危险。

13.产生什么结果?为什么?

#include "stdio.h"
#include "string.h"

int main()
{
	char s[10];
	strcpy(s,"0123456789");
	return 0;
}

结果:段错误,因为数组长度为10,只能放下10个字符串,而"0123456789"字符串后面还有一个\0字符串,超过数组长度了。

14.数组和链表的区别

①存储方式不同:

数组是连续存储的,数组在创建的时候需要一整块的空间。

链表是链式存储,链表在内存空间中不一定是连续的。

数组一般创建在栈区,链表一般创建在堆区,再增加节点时需要new或malloc新节点,相较于数组长度不固定,自由度高。

②访问元素方式不同

数组可以通过下标随机访问,单向链表只能通过头结点从前向后访问链表中的元素。

③增删效率不同

数组在插入和删除的时候需要移动链表中的其他元素,时间复杂的为O(n)。

链表在进行插入删除时,找到要插入或删除的位置后,增删时间复杂度为O(1)。

当线性表进行大量的插入和删除的操作时建议使用链表,若主要对线性表及逆行查找操作,较少进行插入操作时建议使用数组。

15.会出现什么问题?打印结果是是多少?

void main()
{
  char aa[10];
  printf("%d",strlen(aa));
}

sizeof()和初不初始化,没有关系,

strlen()和初始化有关,打印结果值未知

16.

struct A
{
  char t:4;
  char k:4;
  unsigned short i:8;
  unsigned long m;
};

问sizeof(A) = ?

答案:1 + 1 + 2 + 4 = 8

17.求sizeof(name1)?

struct name1
{
  char str;
  short x;
  int num;
};

答案:1 + 1 + 2 + 4 =8

18.求sizeof(name2)?

struct name2
{
  char str;
  int num;
  short x;
};

答案:4 + 4 + 2 + 2 = 12

19.程序哪里有错误

wap( int* p1,int* p2 )
{
  int *p;
  *p = *p1;
  *p1 = *p2;
  *p2 = *p;
}

答案:第一个创建的指针变量p没有初始化,此时为野指针。

20.(void *)ptr 和 (*(void**))ptr的结果是否相同?其中ptr为同一个指针

答案:结果相同,因为*ptr对per进行解引用正好抵消per*。

21.

要对绝对地址0x100000赋值,我们可以用(unsigned int*)0x100000 = 1234;

那么要是想让程序跳转到绝对地址是0x100000去执行 ,应该怎么做?

答案:首先要将0x100000强制转换成函数指针,即*((void(*)())0x100000)();

22.运行Test函数会有怎样的结果

char *GetMemory(void)
{
  char p[] = "hello world";
  return p;
}
void Test(void)
{
  char *str = NULL;
  str = GetMemory();
  printf(str);
}

答案:可能是乱码,因为GetMemory返回的是”栈内存“的指针,该指针的地址不是NULL,但其原先的内容已经被清除,新内容不可知。

23.关于内存的思考问题,运行Test会出现什么结果

void GetMemory(char **p,int num)
{
  *p = (char *)malloc(num);
}
void Test(void)
{
  char *str = NULL;
  GetMemory(&str,100);
  strcpy(str,"hello");
  printf("%s\r\n",str);
}

答案:①输出hello      ②内存泄漏

24.运行Test会出现什么结果

void Test(void)
{
  char *str = (char *)malloc(100);
  strcpy(str,"hello");
  free(str);
  if(str !=NULL)
  {
    strcpy(str,"world");
    printf("%s\n",str);
  }
}

答案:经过free(str)之后,str就被释放了,if(str !=NULL)不起作用。

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

答案:volatile含义:被volatile修饰过的变量表示不想在不经意间被修改,因此编译器在读取整个被修饰过的变量时,会重新读取这个变量的值,而不是使用在寄存器中保存的备份。

①并行设备的硬件寄存器。

②一个终端服务子程序中会访问到的非自动变量。

③多线程应用中被几个任务共享的变量。

26.嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点

嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点,在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯 粹的ANSI编译器。写代码去完成这一任务。

答案:访问一绝对地址把一个整型数强制转换(typecast)为一指针是合法的。

int *ptr = malloc(sizeof(int));
ptr = (int *)0x67a;
*ptr = 0xaa66;

27.

头文件中的 ifndef/define/endif 干什么用?

答案:①防止同一个头文件重复包含。

头文件可能会从多个源文件中被包含。如果没有判断,每次包含都会重复定义它里面的内容,可能导致编译错误,使用#ifndef/#d,efine/#endif可以确保头文件只被定义一次。

         ②避免重复定义

头文件里可能定义了变量或类型等,重复定义就会导致编译错误。使用#ifndef可以避免这种情况。

          ③提高效率

只有在没有定义某个宏时,才会执行后续代码块。如果重复包含,就直接跳过后续代码,提高编译效率。

28.#include <filename.h>和#include “filename.h” 有什么区别

答案:主要区别在于它们引用的头文件搜索路径不同:

  • #include <filename.h>: 会在编译器预定义的系统头文件目录中搜索filename.h头文件。这些目录通常包含标准C/C++库头文件。
  • #include "filename.h": 会先在项目源代码所在目录中搜索filename.h头文件,如果没有找到,则在系统头文件目录中搜索。

所以:

  • 使用#include <filename.h>包括标准库头文件。
  • 使用#include "filename.h"包括项目本身定义的头文件。

总的来说:

  • #include <filename.h>用于标准库头文件
  • #include "filename.h"用于项目内部定义的私有头文件

29.const 有什么用途?(请至少说明两种)

①可以定义 const 常量

②const 可以修饰函数的参数、返回值,甚至函数

的定义体。被 const 修饰的东西都受到强制保护,可 以预防意外的变动,能提高程序的健壮性。

③防止函数或变量的值被改变。比如定义一个常量用const,可以保证其值不会被修改。

④修饰对象表明它是一个只读对象。如定义常量对象const对象,可以使对象的值在程序执行期间保持不变。

30.static有什么用途?

①static修饰全局变量变为静态全局变量,全局变量的作用域改变,生命周期不变,只能在其.c文件中背使用。

②static修饰局部变量变为静态局部变量,局部变量超过生命周期也不会被销毁,改变了局部变量的生命周期,但其作用域还是局部的。

③static修饰函数变为静态函数,函数只能在自己的.c内使用,不能在其他文件中使用。

31.堆栈溢出一般是由什么原因导致的?

答案:没有回收垃圾资源

①函数调用深度过深。

②栈内存分配过大。

③递归调用次数过多。

④没有清理临时变量。

⑤不合理的循环结构。如死循环、死递归。

32.如何引用一个已经定义过的全局变量?

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

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

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

34.队列和栈有什么区别

①规则不同,队列遵循先进先出(First In First Out, FIFO)的原则,栈遵循先进后出(First In Last Out, FILO)的原则。

②遍历数据速度不同,队列可以通过地址指针进行遍历,可以从队列的头部或尾部开始遍历,但不能同时进行。遍历过程中不需要为数据开辟临时空间,因此遍历速度较快。

栈只能从栈顶取数据,如果要取栈底的数据,需要遍历整个栈,并且在遍历的同时需要为数据开辟临时空间,以保持数据在遍历前的一致性。因此,栈的遍历速度相对较慢。

35.Heap(堆)与stack(栈)的差别

①开辟方式不同,heap在堆区开辟,stack在栈区开辟。

②释放方式不同,heap由new或malloc动态开辟,需要手动free释放。

stack由cpu开辟和销毁的。

36.用宏定义写出swap(x,y),即交换两数

#define swap(x,y)
(x) = (x) + (y);
(y) = (x) - (y);
(x) = (x) - (y);

37.写一个“标准”宏,这个宏输入两个参数并返回较小的一个

#define Min(X,Y) ((X>Y)?(Y):(X))

38.带参宏与带参函数的区别(至少说出5点)

C语言面试100道题_整型

39.关键字volatile有什么含意

答案:防止被volatile修饰过的变量被不经意间修改

40.函数既然不会被其它函数调用,为什么要返回1

int main()
{
  int x=3;
  printf("%d",x);
  return 1;
}

答案:mian中,c标准认为0表示成功,非0表示错误。具体的值是某中具体出错信息。

41.已知一个数组table,用一个宏定义,求出数据的元素个数

答案:

#define NTBL(table) (sizeof(table)/sizeof(table[0]))

42.A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)

答案:static修饰的变量只能在该.c文件中被使用,因此他们之间互不影响。这两个变量都存放在静态数据区,但是编译器

对他们的命名不同。如果要使变量在其他模块也有意义的话,需要使用extern关键字

43.static全局变量与普通的全局变量有什么区别?

答案:static全局变量只初使化一次,防止在其他文件单元中被引用。

44.static局部变量和普通局部变量有什么区别

答案:static局部变量只被初始化一次,下一次依据上一次结果值

45.static函数与普通函数有什么区别?

答案:被static修饰过的函数只能在该.c的文件中被调用,而普通函数是有外部调用属性的,其它文件可以通过包含该函数的头文件进行调用。

46.

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

47.什么是预编译,何时需要预编译

答案:预编译是在软件程序运行之前,对程序代码进行编译的过程。

①可以减少运行时编译时间的情况下进行。

②一些性能要求较高的程序。

③对于一些服务器程序,运行时动态编译可能带来的安全隐患的程序。

④对于需要进行频繁部署的程序。

⑤针对不同平台或环境的程序。

48.用两个栈实现一个队列的功能?要求给出算法和思路!

栈结构是先进后出

队列是先进先出

思路:首先设置两个栈分为A、B,两者均为空

入队:

将新元素入栈A,然后出栈,将元素依次入栈B,最后将栈B的栈顶元素依次出栈,就实现了队列的先进先出功能。

过程如下图手画所示:

C语言面试100道题_链表_02

49.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?

答案:c用宏定义,c++用inline

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

答案:#define SECONDS_PER_YEAR    (60 * 60 * 24 * 365)UL

51.Typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。

例如思考一下下面的例子,那个方法更好?

#define dPS struct s *
typedef struct s * tPS

答案:

①明确性:typedef好,typedef struct s *tPS明确表明tPS是一个指向struct s结构体的指针类型。

#define dPS struct s*看起来像是一个结构体,但实际上是一个指针类型,不如typedef明确。

②可读性:

typedef定义的变量名可以直接使用,不需要每次都加struct,相对更清晰易读。

52.在 C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern “C”?

答案:C++语言支持函数重载,C 语言不支持函数重载。

函数被 C++编译后在库中的名字与 C 语言的 不同。

假设某个函数的原型为: void foo(int x, int y); 该函数被 C 编译器编译后在库中的名字为_foo,而 C++编译器则会产生像_foo_int_int 之类的名字。 C++ 提供了 C 连接交换指定符号 extern“C”来解决名字匹配问题。

53.请简述以下两个 for 循环的优缺点

C语言面试100道题_链表_03

答案:代码一优点简洁明了。

缺点:多执行了N-1次逻辑判断,并且打断了循环“流水线”左右,使得编译器不能对循环进行优化处理,降低了效率。

代码二优点循环的效率高。

缺点:程序不够简洁。

53.语句for( ; 1 ; );有什么问题?它是什么意思?

答案:它本身是个死循环,与while(1)相同。

54.do……while和while……do有什么区别

答案:前者是先执行后判断,若条件符合继续执行,后者是先判断是否符合条件,若符合条件再执行。

55.请写出下列代码的输出内容

#include <stdio.h>
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;
}

答案:10、12、120

56.求以下答案

unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
p1+5= ;//指针+1步长为类型大小0x801000+1*5
p2+5= ;//0x810000+4*5

答案:0x801005、0x810020

57.求输出答案

main()
{
  int a[5]={1,2,3,4,5};
  int *ptr=(int *)(&a+1);
  //此时ptr指向的为第二行第一个元素,但ptr-1表示往回挪动了一位,也就是指向了第一行的最后一个元素
  printf(“%d,%d”,*(a+1),*(ptr-1));
}

答案:2、5

58.请问下面程序有什么错误?

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(k=0;k<=60;k++)
	for(j=0;j<250;j++)
		for(i=0;i<1000;i++)
a[i][j][k]=0;

59.以下是求一个数的平方的程序,请找出错误

#define SQUARE(a)((a)*(a))
int a=5;
int b;
b=SQUARE(a++);

答案:宏在预编译时会以替换的形式展开,仅仅会替换。涉及到宏的地方,不要用++ --,标准中对此 没有规定,因此最终结果将会依赖于不同的编译器。 执行程序的答案可能是25、也有可能是36

60.这段代码执行有什么问题?

#define Max_CB 500
void LmiQueryCSmd(Struct MSgCB * pmsg)
{
  unsigned char ucCmdNum;
  ...... 
  for(ucCmdNum=0;ucCmdNum<Max_CB;ucCmdNum++)
  {
     ......;
  } 
}

答案:死循环,unsigned char为无符号字符型大小在0-255,char为有符号型,范围在-128~127。

61.嵌入式系统中经常需要写无限循环,该怎么写?

答案:while(1){}或for( ; ; )循环

62.程序的输出结果是什么?

C语言面试100道题_整型_04

答案:8、10、12、14、16

63.求输出结果

C语言面试100道题_数组_05

答案:16

64.求输出结果

int modifyvalue() 
{
  return(x+=10);
}
int changevalue(int x)
{ 
  return(x+=1);
}
void main()
{ 
  int
  x=10;
  x++;
  changevalue(x);
  x++;
  modifyvalue(); 
  printf("First output:%dn",x);
  x++;
  changevalue(x); 
  printf("Second output:%dn",x); 
  modifyvalue();
  printf("Thirdoutput:%dn",x);
}

答案:12、13、13

65.不能做switch()的参数类型是

答案:switch的参数不能为实型

  1. 确保switch后面括号内的表达式的值为整数类型。如果表达式的值不是整数类型,可以通过类型转换将其转换为整数类型。

2.确保case后面的值都是整数常量。

66.请写出下列代码的输出内容

#include<stdio.h>
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;
}

答案:10、12、120

67.找出程序的错误

C语言面试100道题_整型_06

68.一语句实现x是否为2的若干次幂的判断。

void main() 
{ 
  int a; 
  scanf("%d",&a); 
  printf("%c",(a)&(a-1)?'n':'y'); // 若是打印y,否则打印n 
}

69.中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。具代表事实是,产生了一个新的关键字 __interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服 务子程序(ISR),请评论一下这段代码的

__interrupt double compute_area (double radius)
{
  double area = PI * radius * radius;
  printf(" Area = %f", area);
  return area;
}

答案:①ISR 不能返回一个值。

②ISR应该是短而有效率的,尽可能不在ISR中做浮点运算。

③)ISR 不能传递参数。

④中断中不能有printf

70.下面的代码输出是什么,为什么?

void foo(void)
{
  unsigned int a = 6;
  int b = -20;
  (a+b > 6)? puts("> 6") : puts("<= 6");
}

答案:> 6

当有符号整形和无符号整型进行比较时,需要将有符号整形转为无符号整形,因此-20转成无符号二进制也就是10000000 00000000 00000000 0010100

因此a+b远远大于6

71.评价下面的代码片断

unsigned int zero = 0;
unsigned int compzero = 0xFFFF;
/*1‘s complement of zero */

答案:对于一个int型不是16位的处理器来说,上面的代码是不正确的。

unsigned int zero = 0;
//在任何系统位数上都是正确的,因为都是最小0
unsigned int compzero = 0xFFFF;
//在16位(0~65535),对于unsigned int来说0xFFFF表示最大
//而在32位(0~2^32-1),对于unsigned int来说0xFFFF不能表示最大

72.下面的代码片段的输出是什么,为什么?

char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
puts("Got a null pointer");
else
puts("Got a valid pointer");

答案:在if判断语句中,从左向右进行判断,先判断的是创建malloc(0)个空间地址给ptr,此时ptr便指向了malloc开辟的地址,不再为NULL,因此走了else语句。

73.写一个二分查找的代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int left = 0;//左下标第一个
	int sz = sizeof(arr) / sizeof(arr[0]);//元素个数
	int right = sz - 1;//右下标倒数第一个
	printf("请输入你想要打印的值:>");
	int k = 0;
	scanf("%d", &k);
	while (left <= right)
	{
		int mid = (left + right) / 2;//中间下标
		if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else
		{
			printf("找到了,下标是 : %d", mid);
			break;
		}
	}
	if (left > right)
	{
		printf("找不到");
	}
	return 0;
}

74.请编写一个 C 函数,该函数给出一个字节中被置为1的个数

#include <stdio.h>
int main()
{
	int k,a,b,count=0;
	printf("请输入你想要查找的数\n");
	scanf("%d",&k);
	while(1)
	{
		a = k/2;
		b = k%2;
		if(b==1)
		count++;
		k=a;
		if(k==0)
		{
			printf("你输入的数中二进制中1的个数为%d个\n",count);
			break;
		}
	}
	return 0;
}

75.请编写一个 C 函数,该函数将给定的一个字符串转换成整数

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[20]="\0";
	printf("请输入你想转换的字符串\n");
	scanf("%s",arr);
	int n = strlen(arr)-1;

		for(int i=0;i<=n;i++)
		{
			printf("%c = %d\n",arr[i],arr[i]-48);
		}	
}

76.请编写一个 C 函数,该函数将给定的一个整数转换成字符串

#include <stdio.h>
#include <string.h>
int main()
{
	int arr[5]={0};
	int n = sizeof(arr)/sizeof(arr[0]);
	printf("请输入你想转换的整数,回车结束\n");
	for(int i=0;i<n;i++)
	{
		scanf("%d",&arr[i]);
	}
		for(int i=0;i<n;i++)
		{
			printf("%d = %c\n",arr[i],arr[i]+48);
			
		}	
		printf("转化后的字符串为:");
		for(int i=0;i<n;i++)
		{
			printf("%c",arr[i]+48);
		}
		return 0;
}

77.写一个函数实现strcmp函数功能

#include<stdio.h>
int my_strcmp(char* str1,char* str2)
{
	do
	{
		if(*str1>*str2)
		return 1;
		else if(*str1<*str2)
		return -1;
	}while((*str1++)&&(*str2++));
	return 0;
}
int main()
{
	char s1[20],s2[20];
	printf("请输入第一个字符串\n");
	//gets(s1);
	scanf("%s",s1);
	printf("请输入第二个字符串\n");
	//gets(s2);
		scanf("%s",s2);
	if(my_strcmp(s1,s2)>0)
		printf("%s比%s大\n",s1,s2);
	else if(my_strcmp(s1,s2)<0)
		printf("%s比%s小\n",s1,s2);
	else
		printf("%s与%s相等\n",s1,s2);

}

78.请编写一个 C 函数,该函数将一个字符串逆序

#include <stdio.h>
#include <string.h>
char *rever(char *str);
int main(int argc, char *argv[])
{ 
    char a[64]={0};
    char *temp;
    printf("please input your str:");
    gets(a);
    printf("your str is:%s\n",a);
    temp=rever(a);
    printf("reverse is %s\n",temp);
    return 0;
} 

char *rever(char *str)
{
    int len = strlen(str);
    char b[64]={0};
    strcpy(b,str);
    char temp;
    for(int i=0;i<len/2;i++)
    {
        temp = b[i];
        b[i] = b[len-i-1];
        b[len-i-1] = temp;
    }
    strcpy(str,b);
    return str;
}

79.编写函数实现strcpy功能

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void my_strcpy(char *dest, char *src)
{
	while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = '\0';
}
int main()
{
	char dest[50];//目的地
	char src[10] = "abc123";//目标文件
	my_strcpy(dest,src);
	printf("%s",dest);
	return 0;
}

80.不使用strcat实现其功能

#include<stdio.h>
#include<string.h>
void my_strcat(char *dest,char *src)
{
	int a=strlen(dest);//计算出dest数组内有多少个字符
	dest+=a;//越过指定数量的字符,以便于在其后追加src里的字符
	while(*src!='\0')
	{
		*dest=*src;
		dest++;
		src++;
	}
	*dest='\0';
}
int main()
{
	char dest[32]="hello";
	char src[32]="world";
	my_strcat(dest,src);
	printf("%s\n",dest);
	return 0;
}

81.请编写一个 C 函数,该函数在给定的内存区域搜索给定的字符,并返回该字符所在位置索引值。

#include <stdio.h>
#include <string.h>

int search(char *str,char cc,int a,int b)
{
	int i,j=0;
	j=strlen(str);
	for(i=0;i<=j;i++)
	{
		if(cc==str[i])
			return i;
	}
	return -1;
}
int main()
{
	char *str="hello world";
	char c=0;
	int a,b=0;
	printf("请输入你想找的字符\n");
	scanf("%c",&c);
	getchar();
	printf("请输入要查找的起始位置\n");
	scanf("%d",&a);
	printf("请输入要查找的结束位置\n");
	scanf("%d",&b);
	int d = search(str,c,a,b);
	if(d>a&&d<b)
	{
		printf("找到了下标是%d\n",d);
	}
	if(d==-1)
	{
		printf("找不到\n");
	}
	return 0;
}

82.请编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,该字符串是由同一字符组成的。