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");
}
20160216.CCPP体系详解(0026天)的更多相关文章
- 20160129.CCPP体系详解(0008天)
程序片段(01):函数.c+call.c+测试.cpp 内容概要:函数 ///函数.c #include <stdio.h> #include <stdlib.h> //01. ...
- 20160226.CCPP体系详解(0036天)
程序片段(01):01.多线程.c+02.多线程操作.c 内容概要:多线程 ///01.多线程.c #include <stdio.h> #include <stdlib.h> ...
- 20160208.CCPP体系详解(0018天)
程序片段(01):main.c 内容概要:PointWithOutInit #include <stdio.h> #include <stdlib.h> //01.野指针详解: ...
- 20160206.CCPP体系详解(0016天)
代码片段(01):.指针.c+02.间接赋值.c 内容概要:内存 ///01.指针 #include <stdio.h> #include <stdlib.h> //01.取地 ...
- 20160205.CCPP体系详解(0015天)
程序片段(01):01.杨辉三角.c 内容概要:杨辉三角 #include <stdio.h> #include <stdlib.h> #define N 10 //01.杨辉 ...
- 20160204.CCPP体系详解(0014天)
程序片段(01):define.h+data.h&data.c+control.h&control.c+view.h&view.c+AI.h&AI.c+main.c 内 ...
- 20160203.CCPP体系详解(0013天)
程序片段(01):数组.c+02.数组初始化语法.c 内容概要:数组 ///01.数组.c #include <stdio.h> #include <stdlib.h> //0 ...
- 20160128.CCPP体系详解(0007天)
以下内容有所摘取,进行了某些整理和补充 论浮点数的存储原理:float浮点数与double浮点数的二进制存储原理–>阶码 浮点数转二进制 1.整数int类型和浮点数float类型都是占用4个字节 ...
- 20160127.CCPP体系详解(0006天)
程序片段(01):msg.c 内容概要:线程概念 #include <stdio.h> #include <stdlib.h> #include <Windows.h&g ...
随机推荐
- 区块链3.0:拥抱EOS
EOS是当下最火的区块链技术,被社会广泛看好为下一代区块链3.0.不同于以太坊的学习,EOS的主语言是C++,本文作为EOS研究的首篇文章,重点介绍EOS的创新点,它的周边生态,各种概念原理的解释,以 ...
- Ubuntu+Firefox总是打不开网页
参考链接 火狐的设置里面找: 首选项 -> 高级 -> 网络 -> 连接 -> 设置, 结果发现之前默认是选择了使用系统代理设置, 果断拒绝!... 勾选第一项, " ...
- JAVA_扫雷游戏(布置地雷)
1.要为扫雷游戏布置地雷,扫雷游戏的扫雷面板可以用二维int数组表示.如某位置为地雷,则该位置用数字-1表示, 如该位置不是地雷,则暂时用数字0表示. 编写程序完成在该二维数组中随机布雷的操作,程序读 ...
- laypage分页控件使用方法
laypage是一款非常简单易用的分页控件,由于最近项目中使用到了,简单记录一下使用方法 1.引入laypage所需的js和css文件 <link href="js/laypage/1 ...
- Unity3D UGUI 自动调节大小
可添加以下组件 组件包含的两个枚举参数,可以自行设定适应方式. 例如一个Text UI元素,当文字过多的时候他不会自动增加高度而导致文字不能完全显示,这时候就可以挂载这个组件,如上图设置参数,就可以自 ...
- bzoj 4547 小奇的集合
Description 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大 值.(数据保证这个值为非负数) Input 第一行有两个整数n ...
- 51 nod 1495 中国好区间
1495 中国好区间 基准时间限制:0.7 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 阿尔法在玩一个游戏,阿尔法给出了一个长度为n的序列,他认为,一段好的区间,它的长度是& ...
- 51nod 1179 最大的最大公约数
1179 最大的最大公约数 题目来源: SGU 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 给出N个正整数,找出N个数两两之间最大公约数的最大值.例如:N = ...
- 浅析Linux内核调度
1.调度器的概述 多任务操作系统分为非抢占式多任务和抢占式多任务.与大多数现代操作系统一样,Linux采用的是抢占式多任务模式.这表示对CPU的占用时间由操作系统决定的,具体为操作系统中的调度器.调度 ...
- hdu 3974 线段树 将树弄到区间上
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...