20160216.CCPP体系具体解释(0026天)

程序片段(01):01.MemCpy.c

内容概要:内存拷贝

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

//memcpy:
//  将内存数据依照字节数从一片儿内存复制到还有一片儿内存
//      并返回拷贝成功之后的地址
void * memcpyByIndex(void * dest, const char * src, unsigned int size)
{
    if (NULL == dest || NULL == src)
    {
        return NULL;
    }
    char * pDest = dest;
    for (int i = 0; i < size; ++i)
    {
        *(pDest + i) = *(src + i);
    }
    return dest;
}

void * memcpyByPoint(void * desc, const char * src, unsigned int size)
{
    if (NULL == desc || NULL == src)
    {
        return NULL;
    }
    int i = 0;//同一个for循环其中仅仅同意定义统一类型的变量,决不同意另外一种数据类型的出现
    for (char * p = desc; i < size; ++p)
    {
        *p++ = *src++;
    }
    return desc;
}

//01.同一个for循环其中仅仅同意定义同一个类型的变量!
//  决不同意另外一种数据类型的出现!
int main(void)
{
    int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int * p = (int *)malloc(10 * sizeof(int));
    memcpy(p, arr, 40);
    for (int i = 0; i < 10; ++i)
    {
        printf("%d \n", *(p + i));
    }
    char str[1024] = "Hello Boygod";
    char * pStr = (char *)malloc((strlen(str) + 1)*sizeof(char));
    char * pNew = memcpyByIndex(pStr, str, strlen(str) + 1);
    printf("%s \n", pStr);
    printf("%s \n", pNew);

    system("pause");
}

程序片段(02):01.内存清零.c

内容概要:MemSet

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

//memset:从指定的地址開始,进行内存单字节设置
//  设置总数依照字节数进行决定,并返回设置之后的内存首地址
//特点:针对于数值类型的数组,相当于清零动作;
//      针对于其它类型的数组,相当于字符替换作用!
void * memsetByIndex(void * dest, int value, unsigned int size)
{
    if (NULL == dest)
    {
        return NULL;
    }
    for (int i = 0; i < size; ++i)
    {
        *(((char *)dest) + i) = value;
    }
    return dest;
}

void * memsetByPoint(void * dest, int value, unsigned int size)
{
    if (NULL == dest)
    {
        return NULL;
    }
    for (char * p = (char *)dest; p < (char *)dest + size; ++p)
    {
        *p = value;
    }
    return dest;
}

int main01(void)
{
    int intArr[5] = { 1, 2, 3, 4, 5 };
    double dbArr[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
    char chrArr[1024] = "Hello World";
    memset(intArr, 0, 20);//数据清零
    memsetByIndex(intArr, 0, 20);//数据清零
    memsetByPoint(chrArr, ‘A‘, 1023);//数据替换
    for (int i = 0; i < 5; ++i)
    {
        printf("%d, %lf", intArr[i], dbArr[i]);
    }
    printf("%s \n", chrArr);

    system("pause");
}

程序片段(03):01.内存拷贝.c

内容概要:MemMove

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

//memmove:内存移动:
//  特点:将一个内存块儿其中指定的区域拷贝一份到暂时缓冲区其中
//      在将暂时缓冲区其中的内容直接覆盖到指定内存块儿其中(覆盖!)
//      返回被覆盖内存块儿的首地址
void * memmoveByMemCpy(void * dest, const void * src, unsigned int size)
{//借用memcpy实现memmove
    if (NULL == dest || NULL == src)
    {
        return NULL;
    }
    void * tAddr = malloc(size);
    memcpy(tAddr, src, size);
    memcpy(dest, tAddr, size);
    free(tAddr);//暂时内存缓冲区释放!
    return dest;
}

//01.严格区分memcpy和memmove的拷贝原理差别:
//  1.memcpy是从源地址进行单个字节单个字节的复制到目标地址
//      仅仅有这么一条规则
//  2.memmove是从源地址进行指定字节数先复制到暂时缓冲区
//      然后再将暂时缓冲区其中的字节内存整块儿覆盖到目标地址
//  3.假设不是字节复制到自己的内存环境下,两者都能够互换,一旦涉及
//      到交叉内存拷贝的时候,针对于memcpy会出现故障,针对于memmove
//      不会出现故障!
//  注:实现方式不同,memmove能够借助memcpy进行实现!
int main01(void)
{
    int arrA[5] = { 1, 2, 3, 4, 5 };
    int arrB[5] = { 0 };
    for (int i = 0; i < 5; ++i)
    {
        printf("%d, %d \n", arrA[i], arrB[i]);
    }
    memmoveByMemCpy(arrB, arrA, 20);
    for (int i = 0; i < 5; ++i)
    {
        printf("%d, %d \n", arrA[i], arrB[i]);
    }
    char str1[32] = "abcdefghijklmnopq";
    char str2[32] = "********************";
    memmoveByMemCpy(str2, str1, 6);
    printf("%s, %s \n", str1, str2);
    memmoveByMemCpy(str1 + 2, str1, 4);

    system("pause");
}

程序片段(04):01.MemIcmp.c

内容概要:MemIcmp

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

//memicmp:比对两个内存首地址開始的指定个字节数关系
//  返回值:小于+等于+大于
//注:不仅能够对照内存字节,还能够对照字符串其中的字符
int myMemIcmp(const void * addr1, const void * addr2, unsigned int size)
{
    if (NULL == addr1 || NULL == addr2)
    {
        return 0;
    }
    char * pa = (char *)addr1;
    char * pb = (char *)addr2;
    char * pLast = pa + size;
    int i = 0;
    while (i < size && (*pa == *pb))
    {
        ++pb;
        ++pa;
        ++i;
    }//否则,字节数比对完毕-->相等,单字节小于-->小于,单字节大于-->大于
    if (size == i)
    {
        return 0;
    }
    else if (*pa < *pb)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}

//memchr:从指定的地址開始,在固定字节数的情况下查找单个字符是否存在?

//  存在则,返回其在内存其中的位置
void * memchrByIndex(const void * start, char ch, int size)
{
    for (int i = 0; i < size; ++i)
    {
        if (ch == *((char *)start + i))
        {
            return (char *)start + i;
        }
    }
    return 0;
}

void * memchrByPoint(const void * start, char ch, unsigned int size)
{
    for (char * p = (char *)start; p < (char *)start + ch; ++p)
    {
        if (ch == *p)
        {
            return p;
        }
    }
    return NULL;
}

int main01(void)
{
    int arrA[5] = { 1, 2, 4, 4, 5 };
    int arrB[5] = { 1, 2, 4, 5, 4 };
    char str1[128] = "wuweikbeijing";
    char str2[128] = "wuweijshanghai";
    int i = myMemIcmp(arrA, arrB, 12);
    int j = myMemIcmp(str1, str2, 5);
    printf("%d \n", i);
    printf("%d \n", j);

    system("pause");
}

程序片段(05):01.MemCcpy.c

内容概要:MemCcpy

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//memccpy:将内存数据依照指定字节数从一片儿内存复制到另外一片儿内存,
//  假设复制到特定数值就终止拷贝动作,并返回拷贝之后的目标内存地址
void * memccpyByIndex(void * dest, const void * src, int key, unsigned int size)
{
    if (NULL == dest || NULL == src)
    {
        return NULL;
    }
    for (int i = 0; i < size; ++i)
    {
        if (*((char *)dest + i) = *((char *)src + i) == key)
        {
            return dest;
        }
    }
    return dest;
}

void * memccpyByPoint(void * dest, const void * src, int key, unsigned int size)
{
    if (NULL == dest || NULL == src)
    {
        return NULL;
    }
    char * tmpDest = (char *)dest;
    int i = 0;
    while (i < size)
    {
        //*tmpDest = *((char *)src);
        //if (key == *tmpDest)
        //{
        //  return dest;
        //}
        //++(char *)src;
        //++tmpDest;
        //++i;
        if (*tmpDest++ = *(((char *)src)++) == key)
        {
            return dest;
        }
    }
    return dest;
}

int main01(void)
{
    char str[100] = "i am wuwei, many girs love me!";
    char * pstr = (char[128]) { 0 };//(char[128]){0};//表示栈内存开辟一段儿指定长度的栈内存空间
    pstr = (char *)_memccpy(pstr, str, ‘g‘, 30);
    printf("%s \n", pstr);

    system("pause");
}

程序片段(06):01.Change.c

内容概要:字符串与整数之间的转换

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//atoi:字符串转整数,返回整数
int myAtoi(const char * str)
{
    char * tmpStr = (char *)str;
    while (‘\0‘ != *tmpStr)
    {
        //if (*tmpStr < ‘0‘ || *tmpStr > ‘9‘)
        //{
        //  return -1;
        //}
        if (!(‘0‘ <= *tmpStr && *tmpStr <= ‘9‘))
        {
            return -1;
        }
        ++tmpStr;
    }
    int tmpNum = 0;
    for (int i = 0; i < strlen(str); ++i)
    {
        tmpNum *= 10;//扩大倍数                     //0 10      100
        tmpNum += *(str + i) - ‘0‘;//截取每个字符//0+x   x0+y        xy0+z
    }                                                                   //x xy      xyz
    return tmpNum;
}

//itoa:整数转字符串,
//  1.推断整数位数:
//      1234!=0-->1
//      123!=0---->2
//      12!=0------>3
//      1!=0------->4
//  2.依据位数进行字符逆向填充!
char * myItoa(int num, char * str)
{
    int wei = 0;
    for (int tNum = num; tNum; tNum /= 10)
    {//个位-->1;十位-->2;百位-->3
        ++wei;//统计整数位数
    }
    //逆向填充字符数组,实现整数转字符串
    for (int i = wei - 1; num; num /= 10, --i)
    {
        *(str + i) = num % 10 + ‘0‘;//倒置赋值特点
    }
    *(str + wei) = ‘\0‘;
    return str;
}

int main01(void)
{
    char str1[10] = "1234543";
    int num = myAtoi(str1);
    char str2[20] = { 0 };//严格区分声明和定义:声明-->未开辟+定义-->开辟
    myItoa(1234543, str2);
    printf("%d \n", num);
    printf("%s \n", str2);

    system("pause");
}

程序片段(07):01.AtoF.c

内容概要:AtoF

#include <stdio.h>
#include <stdlib.h>

//atof:字符串转换为实数,返回转换好的实数结果!
//  注:严谨的atof:企业可能自己进行封装和改写函数库!
double myAtof(const char * str)
{
    char * tmpStr = (char *)str;//字符串备份操作
    while (*tmpStr != ‘\0‘)
    {//程序健壮性推断
        if ((‘0‘ > *tmpStr || *tmpStr > ‘9‘) && ‘.‘ != *tmpStr && ‘+‘ != *tmpStr && ‘-‘ != *tmpStr)
        {
            return 0.0;//排除不是标准实数的字符串
        }
        ++tmpStr;
    }
    ++tmpStr;
    double fh = 1.0;
    if (‘-‘ == *str)
    {//符号位检測
        fh *= -1;
        ++str;
    }
    else if (‘+‘ == *str)
    {
        ++str;
    }
    //123=0*10+1-->1*10+2-->12*10+3=>123
    //      0------->10------->100
    //      0*10+x-->x*10+y-->xy*10+z
    //          x               xy                  xyz
    double dbInt = 0.0;
    while (‘.‘ != *str)//处理整数部分
    {
        dbInt *= 10;//0-->10-->100
        dbInt += *str - ‘0‘;
        ++str;
    }
    ++str;
    //  0.234=0.1*2+0.01*3+0.001*4
    //      0.1---------->0.01---------->0.001
    //      1.0*0.1*x---0.1*0.1*y+0.x---0.01*0.1*z+0.xy
    //      0.x             0.xy                        0.xyz
    double dbDb = 1.0;
    while (‘\0‘ != *str)
    {
        dbDb /= 10;
        dbInt += dbDb*(*str - ‘0‘);
        ++str;
    }
    dbInt *= fh;
    return dbInt;
}

int main01(void)
{
    char str[20] = "+12387.2356";
    double db = myAtof(str);
    printf("%lf \n", db);

    system("pause");
}

程序片段(08):01.实数转字符串.c

内容概要:实数转字符串

#include <stdio.h>
#include <stdlib.h>

//ftoa:实数转字符串,返回值为转换之后的字符串
char * ftoa(double db, char * str)
{
    char * tmpStr = str;
    if (db < 0)
    {
        *str = ‘-‘;
        db *= -1;
        ++str;
    }
    //实数:12345.456
    //  整数部分:12345
    //  实数部分:0.456
    int iNum = (int)db;
    int wei = 0;
    //统计整数的位数:
    //  1234
    //      1234!=0-->1
    //      123!=0---->2
    //      12!=0------>3
    //      1!=0-------->4
    for (int i = iNum; i; i /= 10)
    {
        ++wei;
    }
    //  1234:
    //      1234%10-->4
    //      123%10---->3
    //      12%10------>2
    //      1%10-------->1
    for (int i = wei - 1; i >= 0; iNum /= 10, --i)
    {
        str[i] = iNum % 10 + ‘0‘;
    }
    str += wei;//指针跨级跳转
    *str = ‘.‘;//处理小数点
    //str[wei] = ‘\0‘;
    double dbDb = db - (int)db;//获取小数位
    int dbPlace = 0;
    //0.123
    //  0.123*10-->(int)1.23-->1-->0.23
    //  0.23*10---->(int)2.3-->2-->0.3
    //  0.3*10------>(int)3.0-->3-->0.0-->结束
    //不断获取小数位
    //  条件:dbDb!=(int)dbDb;
    for (double iDb = dbDb;; iDb *= 10)
    {//没时间进行小数位的准确判定!
        ++dbPlace;
        if (6 < dbPlace)
        {
            break;//限定小数位精度!
        }
    }

    for (int i = 0; i < dbPlace; ++i)
    {
        dbDb *= 10;//1.23(1)-->12.3(2)-->123(3)
        int data = (int)dbDb;//1-->2-->3
        dbDb -= data;//小数归置:0.23-->0.3-->0.0
        ++str;
        *str = data + ‘0‘;
    }
    *(++str) = ‘\0‘;
    return tmpStr;
}

int main01(void)
{
    double db = 12345.875;
    char str[100] = { 0 };
    //sprintf(str, "%lf", db);
    ftoa(db, str);
    printf("%s \n", str);

    system("pause");
}
时间: 2024-08-04 11:58:59

20160216.CCPP体系具体解释(0026天)的相关文章

20160208.CCPP体系具体解释(0018天)

程序片段(01):main.c 内容概要:PointWithOutInit #include <stdio.h> #include <stdlib.h> //01.野指针具体解释: // 1.野指针:没有进行初始化操作的指针-->由于该指针变量内部所存储的地址是个随机值,因此是野地址(类型含义:指针) // 注:指针类型的变量必须在其被创建的时候就须要进行初始化操作,否则就成了野指针,所谓野指针就是乱指向的指针,形成的就是一个随机垃圾地址 // 2.胡乱使用野指针所造成的现象

20160205.CCPP体系具体解释(0015天)

程序片段(01):01.杨辉三角.c 内容概要:杨辉三角 #include <stdio.h> #include <stdlib.h> #define N 10 //01.杨辉三角: // 1.图形转换:将标准杨辉三角採用标准数组进行模拟 // 2.确定标准数组的图形描写叙述关系: // (1).数组其中第一列的全部元素以及正对角线的全部元素都为1 // (2).数组其中的其他元素等于上一行左一列 // 3.数组模拟杨辉三角的诀窍! // 将整个杨辉三角向左倾斜成为标准的二维数组

20160223.CCPP体系具体解释(0033天)

程序片段(01):MyArray.h+MyArray.c+main.c 内容概要:数组库 ///MyArray.h #pragma once #define DT int//类型通用 typedef struct { DT * pStart;//起始地址 int len;//元素个数 int sortState;//排序状态(0无序+1有序) }Array; typedef struct { DT ** ppStart; int len; }ResArray; void initArray(Ar

20160208.CCPP体系详解(0018天)

程序片段(01):main.c 内容概要:PointWithOutInit #include <stdio.h> #include <stdlib.h> //01.野指针详解: // 1.野指针:没有进行初始化操作的指针-->由于该指针变量内部所存储的地址是个随机值,因此是野地址(类型含义:指针) // 注:指针类型的变量必须在其被创建的时候就需要进行初始化操作,否则就成了野指针,所谓野指针就是乱指向的指针,形成的就是一个随机垃圾地址 // 2.胡乱使用野指针所造成的现象:

20160226.CCPP体系详解(0036天)

程序片段(01):01.多线程.c+02.多线程操作.c 内容概要:多线程 ///01.多线程.c #include <stdio.h> #include <stdlib.h> #include <Windows.h> #include <process.h> //01.线程任务函数剖析: // 1."封装"线程任务代码 // 2.MessageBox();作用: // 用于"阻塞"当前线程的继续执行状态 // 也就是

20160219.CCPP体系详解(0029天)

程序片段(01):ReplaceAll.c 内容概要:ReplaceAll #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> //01.(删除+替换)所有指定字符串 // (双索引+双指针)-->(删除+替换)原理 // 注:增加(拓展)+删除(压缩)+修改(压缩|不变|拓展)+查询(不变) void replaceAll(char

20160220.CCPP体系详解(0030天)

程序片段(01):对称.c 内容概要:对称 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> //01.对称原理: // 1.双索引or双指针-->双边对称夹逼-->进行字符比对 // 2.判断存在情况,默认所有情况 int isSemmetry(char * pStr) { char * p1 = pStr; char * p

20160206.CCPP体系详解(0016天)

代码片段(01):.指针.c+02.间接赋值.c 内容概要:内存 ///01.指针 #include <stdio.h> #include <stdlib.h> //01.取地址操作符(&)详解: // 1.操作对象:变量名(实质:内存实体|数据实体) // 2.操作特点:属于寄存器操作(操作结果不是内存实体) // (1).取地址操作(&变量名)是在CPU的寄存器区域所完成的操作; // (2).地址数据不占用内存,内存地址是在CPU核心构成组件寄存器产生的, /

20160211.CCPP体系详解(0021天)

程序片段(01):01.指针数组.c+02.动态数组.c 内容概要:指针数组 ///01.指针数组.c #include <stdio.h> #include <stdlib.h> //01.指针数组作为函数的形参: // 会退化为一个二级指针! //02.如何确定一个数组作为函数形参将会退化为什么样儿的指针? // 关键在于形参数组当中的元素是什么类型!就是什么类型的指针 void show01(char * str[5])//char *str[5] { for (int i