背景:嵌入式固件岗,偏爱手写库函数、位运算、数组基础算法
一.字符串组
题1:手写 strlen
uint32_t my_strlen(const char *s) {
if (s == NULL) return 0;
const char *p = s;
while (*p != '\0') p++;
return (uint32_t)(p - s);
}
题2:手写 memcpy,处理内存重叠
void *my_memcpy(void *dest, const void *src, uint32_t n) {
if (dest == NULL || src == NULL) return NULL;
uint8_t *d = (uint8_t *)dest;
const uint8_t *s = (const uint8_t *)src;
if (d > s && d < s + n) { // 重叠且 dest 在后:从后往前
d += n; s += n;
while (n--) *--d = *--s;
} else { // 不重叠或 dest 在前:从前往后
while (n--) *d++ = *s++;
}
return dest;
}
题3.手写strcpy
void my_strcpy(char *dst, const char *src)
{
// 判空!嵌入式必写
if(NULL == dst || NULL == src)
{
return;
}
while(*src != '\0')
{
*dst = *src;
dst++;
src++;
}
*dst = '\0'; //手动补结束符
}
题4:查找子串
char *my_strstr(const char *haystack, const char *needle) {
if (haystack == NULL || needle == NULL) return NULL;
if (*needle == '\0') return (char *)haystack;
for (const char *h = haystack; *h != '\0'; h++) {
const char *h2 = h, *n2 = needle;
while (*h2 && *n2 && *h2 == *n2) { h2++; n2++; }
if (*n2 == '\0') return (char *)h;
}
return NULL;
}
题5.字符串原地反转(不开新数组)
void str_reverse(char *str)
{
if(NULL == str)
return;
//求长度
int len = 0;
char *p = str;
while(*p != '\0')
{
len++;
p++;
}
int i = 0;
int j = len -1;
char tmp;
while(i < j)
{
tmp = str[i];
str[i] = str[j];
str[j] = tmp;
i++;
j--;
}
}
二、位运算与进制转换
题1:位操作宏
#define GET_BIT(x, n) (((x) >> (n)) & 1u)
#define SET_BIT(x, n) ((x) |= (1u << (n)))
#define CLR_BIT(x, n) ((x) &= ~(1u << (n)))
#define TOGGLE_BIT(x, n) ((x) ^= (1u << (n)))
题2:判断是否为2的幂
int is_power_of_two(uint32_t x) {
return x != 0 && (x & (x - 1)) == 0;
}
题3:十进制转二进制/十六进制输出
void print_binary(uint32_t x) {
for (int i = 31; i >= 0; i--) {
putchar(((x >> i) & 1u) ? '1' : '0');
if (i % 4 == 0 && i != 0) putchar(' ');
}
putchar('\n');
}
void print_hex(uint32_t x) {
char buf[9]; int i = 8; buf[i] = '\0';
if (x == 0) { puts("0"); return; }
while (x && i > 0) {
int d = x & 0xF;
buf[--i] = (d < 10) ? ('0' + d) : ('a' + d - 10);
x >>= 4;
}
puts(&buf[i]);
}
题4:循环右移
uint32_t rotr(uint32_t x, int k) {
k &= 31; // 防 k 超范围
if (k == 0) return x;
return (x >> k) | (x << (32 - k));
}
题5.统计一个无符号整数二进制里面 1 的个数
uint32_t count_one(uint32_t val)
{
uint32_t cnt = 0;
while(val != 0)
{
val = val & (val -1); //清除最低位的1
cnt++;
}
return cnt;
}
三、数组处理
题1:冒泡排序(带 flag 优化)
void bubble_sort(int *a, int n) {
if (a == NULL || n <= 1) return;
for (int i = 0; i < n - 1; i++) {
int swapped = 0;
for (int j = 0; j < n - 1 - i; j++) {
if (a[j] > a[j + 1]) {
int t = a[j]; a[j] = a[j + 1]; a[j + 1] = t;
swapped = 1;
}
}
if (!swapped) break;
}
}
题2:二分查找(防溢出)
int binary_search(const int *a, int n, int target) {
if (a == NULL || n <= 0) return -1;
int low = 0, high = n - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (a[mid] == target) return mid;
else if (a[mid] < target) low = mid + 1;
else high = mid - 1;
}
return -1;
}
题3:有序数组原地去重
int remove_duplicates(int *a, int n) {
if (a == NULL || n == 0) return 0;
int k = 1;
for (int i = 1; i < n; i++) {
if (a[i] != a[k - 1]) a[k++] = a[i];
}
return k;
}
题4:一遍扫描找最大值/次大值
void find_max2(const int *a, int n, int *max1, int *max2) {
*max1 = *max2 = INT_MIN;
for (int i = 0; i < n; i++) {
if (a[i] > *max1) { *max2 = *max1; *max1 = a[i]; }
else if (a[i] > *max2 && a[i] != *max1) *max2 = a[i];
}
}
四.链表组
题1.单链表反转(迭代版,固件常考)
typedef struct Node
{
int data;
struct Node *next;
}Node;
Node* list_reverse(Node *head)
{
if(NULL == head)
return NULL;
Node *pre = NULL;
Node *cur = head;
Node *next = NULL;
while(cur != NULL)
{
next = cur->next; //保存下一个
cur->next = pre;
pre = cur;
cur = next;
}
return pre; //新头节点
}