嵌入式常见手撕题

字符串相关

strcpy

char *strcpy(char *dest, const char *src)

把 src 所指向的字符串复制到 dest,返回一个指向最终的目标字符串 dest 的指针。要注意内存重叠问题

char * strcpy(char *dest, const char *src) {
 	if (!dest || !src) return NULL;
    char *d = dest;
    int size = strlen(src) + 1;
    if (d > src && d < src + size) {
        d = d + size - 1;
        src = src + size - 1;
        while (size--) 
			*d-- = *src--;
    } 
	else {
        while (size--)  
			*d++ = *src++;
    }
    return dest;
}

memcpy

void *memcpy(void *dest, void *source, unsigned n);

以source指向的地址为起点,将连续的n个字节数据,复制到以destin指向的地址为起点的内存中。返回一个指向dest的指针

void * memcpy(void *dest, const void *src, size_t n) {
    if (!dest || !src) return NULL;
    char *d = (char *) dest;
    const char *s = (const char *) src;
    if (d > s && d < s + n) {
        d = d + n - 1;
        s = s + n - 1;
        while (n--) 
			*d-- = *s--;
    } 
	else {
        while (n--) 
			*d++ = *s++;
    }
    return dest;
}

strcmp 

int strcmp(const char *s1,const char *s2);

比较两个字符串的大小,一个字符一个字符比较,按ASCLL码比较,返回的值是第一个不一样的字符的ASCII值之差

int strcmp(const char* str1,const char* str2) {
    while(*str1 == *str2 && *str1 != '\0') {
        str1++;
        str2++;
    }
    return *str1-*str2;
}

strcat 

char *strcat(char *dest, const char *src)

追加拷贝,将src的内容追加到目标空间dest后面,目标空间必须足够大,能容纳下源字符串的内容,返回一个指向dest的指针

char* strcat(char* dest,const char* src) {
    char* d = dest;
    while(*d!='\0') 
		d++;
		
    while(*src!='\0') 
        *d++=*src++;
    *d='\0';
    return dest;
}

strstr 

char *strstr(const char *str1, const char *str2)

 判断字符串str2是否是str1的子串。如果是,则返回 str1字符串在str2字符串中第一次出现的位置一直到 str1结尾的字符串;否则,返回NULL。


char* strstr(char *str1, char *str2) {
    if (str1 == NULL || str2 == NULL) return NULL;
    char *s = str1;
    if (*str2 == '\0') {
        return NULL;//若str2为空,则直接返回空
    }
    while (*s != '\0') {//若不为空,则进行查询
        char *s1 = s;
        char *s2 = str2;
        while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2) {
            s1++, s2++;
        }
        if (*s2 == '\0') {
            return s;//若s2先结束
        }
        if (*s2 != '\0' && *s1 == '\0') {
            return NULL;//若s1先结束而s2还没结束,则返回空
        } 
        s++;
    }
    return NULL;
}

宏定义

输入两个参数并返回较小的一个

#define MIN(x,y) ((x)>(y)?(x):(y))

加入括号为了防止负号出现

交换两个参数值

#define SWAP(x,y) 
do{ \
    (x) = (x) + (y); \
    (y) = (x) - (y); \
    (x) = (x) - (y); \
}while(0)

求结构体内一个变量相较于结构体的偏移

#define OFFSET(struct,m) (unsigned int)&(((struct*)0)->m)

既然是偏移,那就需要一个首地址+偏移地址。

那么首地址+偏移地址的计算就可以看成:&( ((struct*)x)->m ) - &(struct*)x;

这里做了一个取巧,将首地址变成了(struct*)0;

就可以简化成:&(((struct*)0)->m) - &(struct*)0   ---->   &((struct*)0)->m

(struct*)0  表示假设在0地址处有一个结构体struct
((struct*)0)- >m 表示在0地址处的结构体struct的成员m
&(((struct*)0)- >m) 表示在0地址处的结构体struct的成员m 的地址
(unsigned int)&(((struc*)0)->m) 将0地址处的结构体struct的成员m 的地址转换成整数类型​

已知数组table,求出table的元素个数

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

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 什么是嵌入式系统? 嵌入式系统是一种特殊的计算机系统,它通常被嵌入到其他设备中,如智能机、电视、汽车、医疗设备等。嵌入式系统具有低功耗、高性能、实时性要求等特点。 2. 嵌入式系统与普通计算机有什么不同? 嵌入式系统通常具有较小的尺寸、低功耗、高可靠性、实时性要求以及特定的功能需求。它们的硬件和软件都是为了满足特定的应用需求而设计的。 3. 嵌入式系统中常用的处理器架构有哪些? 常见的处理器架构包括ARM、MIPS、PowerPC、x86等。 4. 嵌入式系统中常用的操作系统有哪些? 常见嵌入式操作系统包括FreeRTOS、uC/OS、Linux、Windows CE等。 5. 嵌入式系统中常用的通信协议有哪些? 常见的通信协议包括UART、SPI、I2C、CAN、USB、Ethernet等。 6. 嵌入式系统中常用的编程语言有哪些? 常见的编程语言包括C、C++、Assembly等。 7. 嵌入式系统中如何进行调试? 常用的调试方法包括printf调试、LED指示灯调试、仿真器调试、逻辑分析仪调试等。 8. 嵌入式系统中如何进行电源管理? 电源管理主要包括功耗控制、电池管理、供电稳定等。常用的电源管理技术包括休眠模式、时钟频率调整、电源管理芯片等。 9. 嵌入式系统中如何进行存储管理? 存储管理主要包括程序存储、数据存储、配置存储等。常用的存储设备包括FLASH、EEPROM、SD卡、硬盘等。 10. 嵌入式系统中如何进行实时性任务调度? 常见的实时任务调度算法包括优先级调度、时间片轮转调度、最短剩余时间优先调度等。常用的实时操作系统包括FreeRTOS、uC/OS等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值