字符串相关
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]))