做一期详细讲解C语言题目(题目就简单描述)(下)

简介: 做一期详细讲解C语言题目(题目就简单描述)

总结一下:


1、首先一组数进行异或得到两个单身狗异或得到的结果。


2、得到异或的结果二进制形式下最低哪个位是1,然后是1的分一组,0的分一组。

void find_single_dog(int arr[], int sz, int* pd1, int* pd2)
{
  int i = 0;
  int ret = 0;
  for (i = 0; i < sz; i++)
  {
  ret ^= arr[i];
  }
  //计算ret二进制中最右边的第几位是1
  //右移和1&
  int pos = 0;
  for (pos=0; pos < 32; pos++)
  {
  if (((ret >> pos) & 1) == 1)
  {
    break;
  }
  }
  for (i = 0; i < sz; i++)
  {
  if (((arr[i] >> pos) & 1) == 1)
  {
    *pd1 ^= arr[i];
  }
  else
  {
    *pd2 ^= arr[i];
  }
  }
}
int main()
{
  //1 2 3 4 5 1 2 3 4 6
  int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  int dog1 = 0;
  int dog2 = 0;
  find_single_dog(arr, sz, &dog1, &dog2);
  printf("%d %d\n", dog1, dog2);
  return 0;
}


四、模拟实现atoi函数


atoi这个函数的主要作用是把字符串数字转换为整型数字。


头文件:int atoi (const char * str);


①函数使用:


1669217140884.jpg


通过测试,我们发现出了一般的数字字符串比如”123456“这样的,我们还要考虑:


1、空指针


2、空字符串


3、空格


4、+-号问题


5、非数字字符


6、越界问题


7、............


#include<stdlib.h>
#include<ctype.h>
#include<ctype.h>
#include<limits.h>
enum Status
{
  VALID, //0
  INVALID //1
}sta=INVALID;//默认非法
int my_atoi(const char* str)
{
  int flag = 1;
  assert(str);//解决空指针
  if (*str == '\0')//解决空字符
  {
  sta = INVALID;
  return 0;//歧义 ,非法0
  }
  //跳过空白字符
  while (isspace(*str))
  {
  str++;
  }
  if (*str == '+')
  {
  flag = 1;
  str++;
  }
  else if(*str=='-')
  {
  flag = -1;
  str++;
  }
  long long ret = 0;
  while (*str)
  {
  if (isdigit(*str))
    //越界
  {
    ret = ret * 10 + flag * (*str - '0');
    if (ret > INT_MAX || ret < INT_MIN)
    {
    //之前的定义为int就不能超过整型最大值,因为超过会发生截断
    //所有要设为long
    return 0;
    }
  }
  else
  {
    return (int)ret;
  }
  str++;
  }
  if (*str == '\0')
  {
  sta = VALID;
  return (int)ret;
  }
}
int main()
{
  //int atoi(const char* str)
  char arr[20] = "-123456";
  int ret=my_atoi(arr);
  if (sta == INVALID)
  {
  printf("非法返回:%d\n", ret);
  }
  else if (sta == VALID)
  {
  printf("合法转换:%d\n", ret);
  }
  //遇到非数字,就停止转换 ,开头遇到空格直接过滤掉,中间遇到空格,停止转换
  return 0;
}

函数说明:


1、assert断言解决空指针问题


2、之所以用long long int 而不用int,是因为如果越界了,int类型会发生截断,不可能大于整型最大值,所以要定义为long long int,这是个细节。


3、使用枚举全局变量的目的是为了一些判断,因为如果是空字符串和"0"字符串如果返回是0,那么这是0还是异常的原因是无法判定的。


五、写一个宏可以把一个整数的二进制位的奇数位和偶数位交换


其实宏和函数差不多,如果感觉宏实现起来有难度,可以尝试先用函数的思想,再转化为宏。对于32位整型,提出来偶数位右移和提出来奇数位左移再相加就实现了奇数位和偶数位的交换。


例子列举:


1669217169298.jpg



#define SWAP_BIT(n)  (((n&0x55555555)<<1)+((n&0xaaaaaaaa)>>1))
int main()
{
  int n = 0;
  scanf("%d", &n);
  int ret=SWAP_BIT(n);
  printf("%d\n", ret);
  return 0;
}


六、替换空格


实现一个函数,将一个字符串中的每个空格替换为"%20".


这道题目不难实现,问题是要想清楚,简单一点,创建一个新的字符串,遍历旧字符串,如果遇到' '就放进去”%20“,然后再把新的字符串拷贝到旧字符串,这是比较笨且浪费空间的做法。


如果我们不创建新的字符串,那么这道题怎么处置呢?我们要对旧的进行扩容,然后要从后往后搬字符,遇到空格就放'0','2','%',这样是不就解决了?


void replaceSpace(char* str, int length)
{
  assert(str);
  //一个空格换成三个字符
  //统计空格,然后增加空格*2
  //从最后往后挪遇到' '就放0 2 %,
  //遇到空格,end2挪动三步
  //end1再往前
  char* cur = str;
  int count = 0;
  //计算空格数
  while (*cur)
  {
  if (*cur == ' ')
  {
    count++;
  }
  cur++;
  }
  int end1 = length - 1;
  int end2 = length + count * 2 - 1;
  while (end1 != end2)
  {
  //We Are Happy.
  if (str[end1] != ' ')
    str[end2--] = str[end1--];
  else
  {
    end1--;
    str[end2--] = '0';
    str[end2--] = '2';
    str[end2--] = '%';
  }
  }
}


七、offsetof宏的实现


设计一个宏,实现offsetof的功能


offsetof的功能是计算结构体成员偏移量,我们知道结构体成员地址是连续的,所以能否借助这一特性来写这样一个代码吗?


分析:

1669217213231.jpg


#define my_offsetof(type,mumber) (size_t)&(((type*)0)->mumber)
typedef struct Stu
{
  char c1;
  int i;
  char c2;
}Stu;
int main()
{
  printf("%d\n", my_offsetof(Stu,c1));
  printf("%d\n", my_offsetof(Stu,i));
  printf("%d\n", my_offsetof(Stu,c2));
  return 0;
}

本期分享就到这里,谢谢大家的观看,也请勘误喔。  

相关文章
|
1月前
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
|
1月前
|
C语言
链式栈实现(C语言描述)
这篇文章介绍了如何在C语言中实现链式栈,包括节点和栈的创建、入栈、出栈、获取栈顶元素、判断栈是否为空以及销毁栈的操作。
20 1
|
1月前
|
C语言
数组栈的实现(C语言描述)
本文介绍了如何在C语言中使用数组来实现栈的数据结构,包括栈的创建、入栈、出栈、获取栈顶元素、检查栈是否为空、获取栈的大小以及销毁栈等操作,并提供了相应的函数实现。
28 1
|
1月前
|
C语言
链式顺序表实现(C语言描述)
本文介绍了如何在C语言中实现链式顺序表,包括数据结构的定义、节点的创建、数据的插入和删除以及链表的打印和销毁。
38 2
|
1月前
|
C语言
顺序表数组法构建(C语言描述)
如何使用C语言通过数组方法构建有序顺序表,包括顺序表的创建、插入、删除和打印等。
18 2
|
1月前
|
C语言
无头链表再封装方式实现 (C语言描述)
如何在C语言中实现无头链表的再封装,包括创建节点和链表、插入和删除操作、查找和打印链表以及销毁链表的函数。
26 0
|
1月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
24 0
|
3月前
|
存储 编译器 C语言
【C语言】指针练习题目
【C语言】指针练习题目
|
5月前
|
测试技术 C语言
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
46 1
|
6月前
|
算法 编译器 API
C语言易混淆、简单算法、结构体题目练习、常见关键字总结-1
C语言易混淆、简单算法、结构体题目练习、常见关键字总结