函数的模拟实现1

简介: 函数的模拟实现1



题一:qsort

练习使用库函数,qsort排序各种类型的数据

qsort<stdlib.h>

//排序任意类型数据

void qsort(void* base, size_t num, size_t size,

   int (*compar)(const void*, const void*));

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//比较函数
int compare(const void* e1, const void* e2)
{
  //int sum = (*(char*)e1 - *(char*)e2);
  return (*(char*)e2 - *(char*)e1);
}
int main()
{
  char arr[] = { 'a','g','q','c','c','b','d','e','o','j'};
  ///*char arr1[5] = "abc";
  //char arr2[5] = "zcd";
  //char arr3[5] = "dde";
  //char arr4[5] = "uef";*/
  ///*char* arr[4] = { arr1,arr2,arr3,arr4 };*/
  int sz = sizeof(arr)/sizeof(arr[0]);
  int n = sizeof(arr[0]);
  qsort(arr,sz,n,compare);
  int i = 0;
  for (i = 0;i < sz;i++)
  {
    printf("%c ", arr[i]);
  }
  /*printf("%s %s %s %s",arr1,arr2,arr3,arr4);*/
  return 0;
}

模拟实现qsort在不同情形的实现

#include <stdio.h>
#include <string.h>
//定义结构体
struct S
{
  char ar1[20];
  int age;
  int  No;
};
//定义一个比较函数
int my_compare(const void* e1, const void* e2)
{
  return (*(char*)e1 - *(char*)e2);
}
//交换
void my_sawp(char* p1,char*p2, size_t n)
{
  size_t i = 0;
  for (i = 0; i < n; i++)
  {
    char tmp = 0;
    tmp = *p1;
    *p1 = *p2;
    *p2 = tmp;
    p1++;
    p2++;
  }
}
//name的比较函数
int my_compare_name(const void* e1,const void* e2)
{
  return strcmp(((struct S*)e1)->ar1, ((struct S*)e2)->ar1);
}
//age的比较函数
int my_compare_age(const void* e1, const void* e2)
{
  return ((*(struct S*)e1).age - (*(struct S*)e2).age);
}
//No的比较函数
int my_compare_No(const void* e1, const void* e2)
{
  return ((*(struct S*)e1).No - (*(struct S*)e2).No);
}
//模拟的qsort
void my_qsort(void* arr,size_t sz,size_t n,int(*my_compare)(const void*e1,const void*e2))
{
  size_t i = 0;
  size_t j = 0;
  for (i = 0; i < sz; i++)
  {
    for (j = 0; j < sz - 1; j++)
    {
      //从小到大,所以用>0
      if (my_compare((char*)arr + n * j, (char*)arr + n * (j + 1)) > 0)
      {
        //达到条件交换
        my_sawp((char*)arr + n * j, (char*)arr + n * (j + 1),n);
      }
    }
  }
}
int main()
{
  //字符数组
  //char arr[] = { 'a','g','q','c','c','b','d','e','o','j' };
  //int sz = sizeof(arr) / sizeof(arr[0]);
  //int n = sizeof(arr[0]);
  //int i = 0;
  //
  //my_qsort(arr, sz,n,my_compare);
  //for (i = 0; i < sz; i++)
  //{
  //  printf("%c ", arr[i]);
  //}
  //结构体
  struct S s1[] = {{ "zhangsan",20,123 }, { "aisi",60,125 }, { "wanwu",70,111 }, { "laoliu",18,106 }};
  int sz1 = sizeof(s1) / sizeof(s1[0]);
  //my_qsort(s1,sz1,sizeof(s1[0]),my_compare_name);
  //my_qsort(s1, sz1, sizeof(s1[0]), my_compare_age);
  my_qsort(s1, sz1, sizeof(s1[0]), my_compare_No);
  
  return 0;
}

题二:strlen

模拟实现strlen

#include <stdio.h>
#include <string.h>
#include <assert.h>
int my_strlen(const char* arr)
{
  assert(arr);
  int count = 0;
  int i = 0;
  for (i = 0; i < 10000; i++)
  {
    if (*(arr + i) != '\0')
    {
      count++;
    }
    else
    {
      break;
    }
  }
  return count;
}
int main()
{
  int n = 0;
  char arr[] = "woxinli" ;
  //n = strlen(arr);
  n = my_strlen(arr);
  printf("%d\n", n);
  return 0;
}

优解一

//计数器方式
int my_strlen(const char * str)
{
 int count = 0;
 while(*str)
 {
  count++;
  str++;
 }
 return count;
}

优解二

//不能创建临时变量计数器
int my_strlen(const char * str)
{
 if(*str == '\0')
  return 0;
 else
  return 1+my_strlen(str+1);
}

优解三

//指针-指针的方式
int my_strlen(char *s)
{
   char *p = s;
   while(*p != ‘\0’ )
       p++;
   return p-s;
}

题三:strcpy

模拟实现strcpy

#include <stdio.h>
#include <string.h>
void my_strcpy(char* arr2,const char* arr1)
{
  int i = 0;
  for (i = 0; i < 10000; i++)
  {
    if (arr1[i] != '\0')
    {
      arr2[i] = arr1[i];
    }
    else
    {
      break;
    }
  }
}
int main()
{
  char arr1[20] = "wojiaoshuaige";
  char arr2[20] = { 0 };
  //strcpy(arr2,arr1);
  my_strcpy(arr2,arr1);
  return 0;
}

优解一

//1.参数顺序
//2.函数的功能,停止条件
//3.assert
//4.const修饰指针
//5.函数返回值
//6.题目出自《高质量C/C++编程》书籍最后的试题部分
char *my_strcpy(char *dest, const char*src)
{ 
 char *ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 
 while((*dest++ = *src++))
 {
  ;
 }
 return ret;
}

题四:strcmp

模拟实现strcmp

#include <stdio.h>
#include <string.h>
#include <assert.h>
int my_strcmp(const char* arr1, const char* arr2)
{
  assert(arr1 && arr2);
  int i = 0;
  for (i = 0; i < 10000; i++)
  {
    if (*(arr1 + i) > *(arr2 + i))
    {
      return 1;
    }
    else if (*(arr1 + i) < *(arr2 + i))
    {
      return -1;
    }
  }
  return 0;
}
int main()
{
  char arr1[20] = "abcdef";
  char arr2[20] = "abcdzf";
  /*int n = strcmp(arr1, arr2);*/
  int n = my_strcmp(arr1,arr2);
  return 0;
}

优解一

int my_strcmp (const char * src, const char * dst)
{
  int ret = 0 ;
 assert(src != NULL);
  assert(dest != NULL);
//&&是当ret为0时,加入循环语句中实现++
  while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
    ++src, ++dst;
  if ( ret < 0 )
    ret = -1 ;
  else if ( ret > 0 )
    ret = 1 ;
  return( ret );
}

题五:strcat

模拟实现strcat

#include <string.h>
#include <stdio.h>
#include <assert.h>
void my_strcat(char* arr1,const char* arr2)
{
  assert(arr1 && arr2);
  int i = 0;
  int sz = 0;
  sz = strlen(arr1);
  for (i = 0; i < 10000; i++)
  {
    if (arr2[i] != '\0')
    {
      arr1[sz] = arr2[i];
      sz++;
    }
    else
    {
      break;
    }
  }
}
int main()
{
  char arr1[20] = "hello ";
  char arr2[20] = "bit ";
  char arr3[20] = "shaniao";
  //strcat(arr1,arr2);
  my_strcat(arr1,arr2);
  my_strcat(arr1,arr3);
  return 0;
}

优解一

char *my_strcat(char *dest, const char*src)
{
 char *ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 while(*dest)
 {
  dest++;
 }
 while((*dest++ = *src++))
 {
  ;
 }
 return ret;
}

题六:strstr

模拟实现strstr

#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strstr(const char* arr1, const char* arr2)
{
  assert(arr1 && arr2);
  int i = 0;
  int j = 0;
  int sz = strlen(arr1);
  int sz1 = strlen(arr2);
  for (i = 0; i < sz; i++)
  {
    int count = 0;
    if (arr1[i] == arr2[0])
    {
      char* p = &arr1[i];
      for (j = 0; j < sz1; j++)
      {
        if (arr1[i + j] == arr2[j])
        {
          count++;
        }
        else if (arr1[i + j] != arr2[j])
        {
          break;
        }
      }
      if (count == sz1)
      {
        return p;
      }
    }
  }
  return NULL;
}
int main()
{
  char arr1[20] = "abcdef";
  char arr2[20] = "def";
  //char* str = strstr(arr1,arr2);
  char* str = my_strstr(arr1, arr2);
  return 0;
}

优解一

char *  strstr (const char * str1, const char * str2)
{
        char *cp = (char *) str1;
        char *s1, *s2;
        if ( !*str2 )
            return((char *)str1);
        while (*cp)
        {
                s1 = cp;
                s2 = (char *) str2;
                while ( *s1 && *s2 && !(*s1-*s2) )
                        s1++, s2++;
                if (!*s2)
                        return(cp);
                cp++;
        }
        return(NULL);
}

题七:memcpy

模拟实现memcpy

#include <stdio.h>
#include <string.h>
void* my_memcpy(void* s2,const void* s1,size_t n)
{
  void* tmp = s2;
  while (n--)
  {
    *((char*)s2) = *((char*)s1);
    s2 = (char*)s2 + 1;
    s1 = (char*)s1 + 1;
  }
  return tmp;
}
int main()
{
  char arr2[20] = { 0 };
  char arr1[20] = "abcdef";
  my_memcpy(arr2,arr1,3);
  //memcpy(arr2, arr1,3);
  return 0;
}

题八:memmove

模拟实现memmove

#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memmove(void* s1,const void* s2,size_t n)
{
  assert(s1 && s2);
  void* tmp = s1;
  
    if(s1 >= s2)//当目标地址大于或等于源地址时
    {
      while (n--)
      {
        *((char*)s1) = *((char*)s2);
        s2 = (char*)s2 + 1;
        s1 = (char*)s1 + 1;
      }
    }
    else
      while (n--)//当目标地址大于或等于源地址时
      {
        *((char*)s1+n) = *((char*)s2+n);
      }
  
  return tmp;
}

或者

void * memmove ( void * dst, const void * src, size_t count)
{
  void * ret = dst;
  if (dst <= src || (char *)dst >= ((char *)src + count)) {
    /*
    * Non-Overlapping Buffers
    * copy from lower addresses to higher addresses
    */
    while (count--) {
        *(char *)dst = *(char *)src;
        dst = (char *)dst + 1;
        src = (char *)src + 1;
   }
 }
  else {
    /*
    * Overlapping Buffers
    * copy from higher addresses to lower addresses
    */
    dst = (char *)dst + count - 1;
    src = (char *)src + count - 1;
    while (count--) {
        *(char *)dst = *(char *)src;
        dst = (char *)dst - 1;
        src = (char *)src - 1;
   }
 }
  return(ret);
}

做错的选择题

关于回调函数描述错误的是( )

A.回调函数就是一个通过函数指针调用的函数

B.回调函数一般通过函数指针实现

C.回调函数一般不是函数的实现方调用,而是在特定的场景下,由另外一方调用。

D.回调函数是调用函数指针指向函数的函数。

调用指针”、“指向函数”是什么鬼……D选项简直逻辑鬼才!ABC就是基础概念,可以复习下。

下面test函数设计正确的是:( )

char* arr[5] = {"hello", "bit"};

test(arr);

A.void test(char* arr);

B.void test(char** arr);

C.void test(char arr[5]);

D.void test(char* arr[5]);

指针的数组传递给子函数变为指针的指针,也就是二级指针。但是允许中括号写法,写成char **arr、char *arr[]、char * arr[5]都可。所以BD正确。

下面程序的结果是:( )

int main()

{

 int aa[2][5] = {10,9,8,7,6,5,4,3,2,1};

 int *ptr1 = (int *)(&aa + 1);//&的优先级大于+

 int *ptr2 = (int *)(*(aa + 1));

 printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));

 return 0;

}

A.1, 6

B.10, 5

C.10, 1

D.1, 5

跟上题类似,&aa的类型是int (*)[2][5],加一操作会导致跳转一个int [2][5]的长度,直接跑到刚好越界的位置。减一以后回到最后一个位置1处。*(aa + 1)相当于aa[1],也就是第二行的首地址,自然是5的位置。减一以后由于多维数组空间的连续性,会回到上一行末尾的6处。故选A。

下面代码中print_arr函数参数设计哪个是正确的?( )

int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};

print_arr(arr, 3, 5);

A.void print_arr(int arr[][],int row, int col);

B.void print_arr(int* arr, int row, int col);

C.void print_arr(int (*arr)[5], int row, int col);

D.void print_arr(int (*arr)[3], int row, int col);

二维数组相当于数组的数组,传到子函数变成数组的指针。int arr[3][5]相当于是3个元素的arr,每个元素是int [5],所以int [5]是类型说明不能省略。丢失的信息只有数组的元素个数,也就是3。A丢了类型中的5,B选项指针层级都错了,D选项5写成了3,故选C。

下面程序的结果是:( )

int main()

{

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

 int *ptr = (int *)(&a + 1);

 printf( "%d,%d", *(a + 1), *(ptr - 1));

 return 0;

}

A.5, 1

B.4, 1

C.4, 2

D.5, 2

*(a + 1)等同于a[1],第一个是4,a的类型是int [5],&a的类型就是int(*)[5],是个数组指针。所以给int(*)[5]类型加一,相当于加了一个int [5]的长度。也就是这个指针直接跳过了a全部的元素,直接指在了刚好越界的位置上,然后转换成了int *后再减一,相当于从那个位置向前走了一个int,从刚好越觉得位置回到了1的地址处,所以第二个是1,故选B。

目录
相关文章
|
7月前
函数的模拟实现
函数的模拟实现
49 0
|
7月前
模拟队列训练
模拟队列训练
37 0
|
28天前
|
前端开发 JavaScript
模拟 new 的实现
模拟 `new` 实现是指在 JavaScript 中,通过自定义函数来模拟内置的 `new` 操作符的行为,以便更好地理解其工作原理和对象构造过程。这种方式通常涉及创建一个新对象、绑定原型链、执行构造函数等步骤。
|
7月前
|
C语言
深入理解并模拟实现函数
深入理解并模拟实现函数
浅谈内存函数以及模拟实现
浅谈内存函数以及模拟实现
70 0
|
Python
抽卡程序模拟
抽卡程序模拟
144 0
内存函数的使用和模拟实现
那么今天我要分享的是内存函数,为什么我会给大家分享这个呢?或者说,内存函数的作用是什么呢?有了字符函数就行了,为什么还会有内存函数呢?那么我们就先来看看字符函数和字符串函数的局限性。字符函数和字符串函数,看见这个名字我们应该就可以知道这个函数的操作对象是什么了,没错,字符函数和字符串函数是操作字符和字符串的,但是平常生活中我们遇到的可不止有字符串,所以这时候就出现了内存函数,它的好处是:可以操作任意类型的数据,这样就极大的方便了我们了我们的生活。接下来我们就来看看这些内存函数是如何使用以及自己来模拟实现它。
|
SQL 监控 前端开发
模拟数据在实际场景中的应用
模拟数据在实际场景中的应用
179 0
模拟数据在实际场景中的应用
|
Go
UCF2016-g2g c u l8r(模拟)
UCF2016-g2g c u l8r(模拟)
86 0