#include <stdio.h> #include <assert.h> size_t mstrlen(const char *s) { assert(s != NULL); if (s == NULL) { return 0; } size_t ret = 0; while (*s != '\0') { ++ret; ++s; } return ret; } void test_strlen() { char a[] = "hello,world"; printf("%lu\n", mstrlen(a)); } char *mstrcpy(char *dst, const char *src) { assert(src != NULL);//若条件不满足(为假),则终止该函数; assert(dst != NULL);//同上. char *pdst = dst; //当函数执行到字符串的末尾时‘ \0’,条件不满足则结束函数 返回“ pdst”. while (*dst = *src) { ++dst; ++src; } /* RTFSD: read the fuck source code */ /* hello,world'\0' = '\0' = 0*/ return pdst;//最后返回的值,结果为指针dst的首地址; } void test_strcpy() //?????? { char d[4] = {0}; char s[] = "hello"; mstrcpy(d,s); printf("strcpy:d:%s\n", mstrcpy(d, s));//结果为strcpy:d:hello printf("%c\n",d[5]);//结果为何还为“"o" ????? } char *mstrncpy(char *dest, const char *src, size_t n) { assert(dest != NULL); assert(src != NULL); char *pdest = dest; //将指针src所指的内容一步步复制给指针dest所指的地址内; while (n--) { if (*src != '\0') { *dest++ = *src++; }else { *dest++ = '\0';//字符串的结束标志复制给指针dest所指的地址,此时复制也就结束了; } } return pdest;//返回指针dest的首地址; } void test_strncpy() { char d[30] = "abcdefghijk"; char s[10] = "hello"; mstrncpy(d,s,8); printf("strncpy:%s\n", mstrncpy(d, s, 8));//结果为strncpy:hello printf("%c,%c,%c\n",d[6],d[7],d[11]);//结果为空白,因为复制过去的没有内容。。 } /*将*src的前n个字符赋给*dest的末尾*/ char *mstrncat(char *dest, const char *src, size_t n) { assert(dest != NULL); assert(src != NULL); char *pdest = dest; while (*dest != '\0') { ++dest;//指针所指的地址依次移动; } while (n--) { if (*src != '\0') { *dest++ = *src++;//将指针src所指地址的值赋给指针dest所指的地址,同时向右移动一个地址; }else { *dest++ = '\0'; } } return pdest; } /*将*src的前n个字节的内容拷贝给*dest,不会因为字符串的结束而结束*/ void *mmemcpy(void *dest, const void *src, size_t n) { char *pdest = (char *)dest; const char *psrc = (char *)src; while (n--) {/*先判断n,再进行自减*/ *pdest++ = *psrc++; } return dest; } void test_memcpy() { char a[] = {0x11, 0x22, 0x33, 0x44, 0x55}; int b = 0; mmemcpy(&b, a, sizeof(b)); printf("b = %#x", b);//结果为0x44332211,按照小端模式排列 printf("b = %x", b);//结果为44332211, } /* s:hello,world accpet: abcde *///在字符串*s中找到最先含有*accept的任一字符的位置并返回,若没有则返回空指针 char *mstrpbrk(const char *s, const char *accept) { assert(s != NULL); assert(accept != NULL); const char *t = NULL;//将空指针赋值给*t; //先在对s进行一层循环 ,后在对accept进行一层循环; for (; *s != '\0'; ++s) { for (t = accept; *t != '\0'; ++t) { if (*s == *t) { return (char *)s;//找到了 就将他的地址返回出来,不再执行后面的语句了; } } } return NULL;//没找到,此时返回空指针; } void test_strpbrk(void) { char s[] = "hello,world"; char a[] = "abcde"; printf("found = %c\n", *mstrpbrk(s, a));//结果为found=e; } //在字符串haystack中查找字符串needle 若找到就返回出来haystack找到的字符串后所以内容, 若没有则返回空指针; char *mstrstr(const char *haystack, const char *needle) { assert(haystack != NULL); assert(needle != NULL); const char *ph = NULL; const char *pn = NULL; for (; *haystack != '\0'; ++haystack) // '0' != '\0' == 0 { for (ph = haystack, pn = needle; (*pn != '\0') && (*ph == *pn); ++ph, ++pn) { ; } /* pn 到达字符结尾*/ if (*pn == '\0') { return (char *)haystack;//返回此时的haystack及后面所跟的所有内容; } } return NULL; } void test_strstr() { char a[] = "hello,worldxwordyfff"; char b[] = "word"; printf("strstr:%s\n", mstrstr(a, b));//strstr:wordyfff } /*字符串反转*/ char *strreverse(char *s) { assert(s != NULL);//断言 char *head = s; char *tail = s; char c = 0; while (*(tail+1) != '\0') { ++tail;//将指针tail的地址移动到最高位; } for (; head < tail; ++head, --tail) { c = *head;/*将指针head指的内容和指针tail指向的内容进行交换*/ *head = *tail; *tail = c; } return s;//为何要返回s??? } void test_strreverse() { char a[] = "hello,world"; printf("strreverse:%s\n", strreverse(a));//结果为strreverse:dlrow,olleh } // "1234" --> 1234 /*将字符型转换成整型*/ int matoi(const char *s) { if (s == NULL) { return 0;/*若为空指针则返回0,并跳出这个函数*/ } int ret = 0; int n = 0; while (*s != '\0') { n = *s - '0';/*将字符型转化成整形*/ ret = ret * 10 + n; ++s;/*向高位自行移动一位地址*/ } return ret;/*返回得到的整型数*/ } void test_atoi() { printf("atoi:%d\n", matoi("1234567")); } /* num = 1234567, buf="1234567" *//*将整型转换成字符型,buf是转换的指针,num被转换成的数组,base转换进制类型*/ char *mitoa(char *buf, int num, int base) { assert(buf != NULL); char tab[] = "0123456789abcdef"; char *pb = buf; while (num != 0) { *pb++ = tab[num % base];/*不断的除进制数进行取余*/ num /= base;//等价于num=num/baes } *pa=\0; #if DEBUG printf("buf=%s\n", buf); #endif return strreverse(buf);//此处是将buf里面的内容进行反转 } void test_itoa() { char buf[20] = {0}; mitoa(buf, 0xf0, 2); printf("itoa:%s\n", buf);//结果为itoa:11110000 (如何输出检测到停止位)? } /*8月6号的任务题目*/ // fmt: "abc%co%dm%x%s%%"// ???没弄懂 int msprintf(char *buf, const char *fmt, ...) { int ret = 0; va_list ap;//你的类型列表 va_start(ap, fmt);//初始化你的ap链表 enum {OFF, ON} flag = OFF;//OFF=0;ON=1 //printf("sizeof(enum)%lu\n", sizeof flag); for (; *fmt != '\0'; ++fmt) { switch (*fmt) { case '%': if (flag == OFF) { //格式位 flag = ON; }else { //普通字符 flag = OFF; *buf++ = *fmt; ++ret; } break; case 'c': if (flag == OFF) { *buf++ = *fmt; }else{ flag = OFF; *buf++ = (char)va_arg(ap, int); } ++ret; break; case 'd': if (flag == OFF) { *buf++ = *fmt; ++ret; }else { flag = OFF; mitoa(buf, va_arg(ap, int), 10); // "1234" while (*buf != '\0') { ++buf; ++ret; } } break; case 'o': if (flag == OFF) { *buf++ = *fmt; ++ret; }else { flag = OFF; mitoa(buf, va_arg(ap, int), 8); // "1234" while (*buf != '\0') { ++buf; ++ret; } } break; case 'x': if (flag == OFF) { *buf++ = *fmt; ++ret; }else { flag = OFF; mitoa(buf, va_arg(ap, int), 16); // "1234" while (*buf != '\0') { ++buf; ++ret; } } break; case 's': if (flag == OFF) { *buf++ = *fmt; ++ret; } else { flag = OFF; mstrcpy(buf, va_arg(ap, char *)); while (*buf != '\0') { ++buf; ++ret; } } break; default: *buf++ = *fmt; ++ret; break; } } va_end(ap); return ret; } void test_sprintf() { char buf[30] = {0}; int n = msprintf(buf, "a%so%dab%c%%%ox%x","hello",1234,'X', 0127, 0x18f); printf("n = %d, buf = %s\n", n, buf);//n=22,buf=ahelloo1234abX%127x18f } int main() { // test_strlen(); // test_strcpy();
.写一个函数判断系统是大端Big_endian还是小端Little_endian 大端格式:字数据的高字节存储在低地址中,而字数据的低字节存放在高地址中 小端格式:字数据的高字节存放在高地址中,而字数据的低字节存放在低地址中 大小端存储问题,如果小端方式中(i占至少两个字节的长度)则i所分配的内存最小地址那个字节中就存着1, 其他字节是0.大端的话则1在i的最高地址字节处存放,char是一个字节,所以强制将char型量p指向i则p指向 的一定是i的最低地址,那么就可以判断p中的值是不是1来确定是不是小端。 int i = 1; char *p = (char*)&i; if(*p == 1) printf("Little_endian"); else printf("Big_endian");
// test_strncpy(); // test_memcpy(); // test_strpbrk(); // test_strstr(); // test_strreverse(); // test_atoi(); test_itoa(); test_sprintf(); return 0; }