计算机网络基础_4_传输层与应用层的作用
2014-02-28 16:50
651 查看
以前发表过关于字符串拷贝函数的实现和分析,那么为什么有了字符串拷贝函数,还需要内存拷贝函数?
一.关于内存拷贝函数的原型和实现。
原型:
void *memmove( void *dest, const void *src, size_t count );
实现:
void* my_memmove(void* p1, void* p2, size_t count)
{
assert(p1);
assert(p2);
char *dest = (char *)p1;
char *src = (char *)p2;
if ((dest > src) && (dest < src + count))
{
while (count--)
{
*(dest + count) = *(src + count);
}
}
else
{
while (count--)
{
*dest = *src;
dest++;
src++;
}
}
return p1;
}
二.内存拷贝函数的意义
1).首先关注函数的参数,void类型指针,告诉我们内存拷贝函数可以接受任意类型。所以就产生一个问题--类型强制转换。为了说明这个问题我们首先看一段程序分析一下。
void *my_memmove(char *dest,const char *src,size_t count)
{
assert(dest);
assert(src);
......
}
上面写的也是内存拷贝函数的一种实现,但是是比较挫的一种实现方式。试着分析一下,这个函数只接收char类型的指针,那么如果要改变的是float型的指针,要怎么办?在传参的时候强制类型转换?那岂不是很麻烦,每当使用这个函数的时候,只要不是char类型的指针都需要强制类型转换。那么,有没有一种一劳永逸的做法?肯定是有,将函数的参数设置成void型,就万事大吉了。只需要在函数实现的内部强制类型转换。
2).内部强制类型转换需要注意的问题
首先应该知道在32位平台上,int型占4字节,float型占4字节,char型占1字节,double型占8字节。那么在函数内部强制类型转换的时候应该转换成什么型呢?
看一个小程序:
void* my_memmove(void* p1, void* p2, size_t count)
{
assert(p1);
assert(p2);
double *dest = (double *)p1;
double *src = (double *)p2;
if ((dest > src) && (dest < src + count))
{
while (count--)
{
*(dest + count) = *(src + count);
}
}
else
{
while (count--)
{
*dest = *src;
dest++;
src++;
}
}
return p1;
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int i = 0;
my_memmove(arr + 4, arr + 2, 16);
for (i = 0; i < 10; i++)
{
printf("%d\n", arr[i]);
}
system("pause");
return 0;
}
当把传进来的参数强制转化为double 程序出现奔溃。试着分析一下。
(1).在内存中数组arr是以4个字节存储,但是在内存拷贝的时候是以8个字节为单位拷贝,说的直白一点就是,要把数组中第一个和第二个元素(1和2)拷贝到8个字节中,那么在输出的时候是用四个字节输出的。输出的内容就是
我们会发现输出的并不是我们想要的。我们要的是 1 2 3 4 3 4 5 6 9 10.
(2)那么用强制转换成什么类型最合适?
不难发现,让指针转换成char类型不会出错。原因就不再啰嗦了。
三.程序为什么分为两种情况?
1).一种情况是从后向前拷贝,一种是从前向后拷贝。
2).试着分析
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; my_memmove(arr + 4, arr + 2, 16); 从前向后拷贝的时候,3放在5的位置,4放在6的位置,该拷贝5的时候,5已经变成了3.和我们的初衷不一样,所以引入了从后向前拷贝的情况。
[b]以上就是本人在学习过程中的一些经验总结。当然,本人能力有限,难免会有纰漏,希望大家可以指正。[/b]
本文出自 “做一个小小小司机” 博客,请务必保留此出处http://10799170.blog.51cto.com/10789170/1715206
一.关于内存拷贝函数的原型和实现。
原型:
void *memmove( void *dest, const void *src, size_t count );
实现:
void* my_memmove(void* p1, void* p2, size_t count)
{
assert(p1);
assert(p2);
char *dest = (char *)p1;
char *src = (char *)p2;
if ((dest > src) && (dest < src + count))
{
while (count--)
{
*(dest + count) = *(src + count);
}
}
else
{
while (count--)
{
*dest = *src;
dest++;
src++;
}
}
return p1;
}
二.内存拷贝函数的意义
1).首先关注函数的参数,void类型指针,告诉我们内存拷贝函数可以接受任意类型。所以就产生一个问题--类型强制转换。为了说明这个问题我们首先看一段程序分析一下。
void *my_memmove(char *dest,const char *src,size_t count)
{
assert(dest);
assert(src);
......
}
上面写的也是内存拷贝函数的一种实现,但是是比较挫的一种实现方式。试着分析一下,这个函数只接收char类型的指针,那么如果要改变的是float型的指针,要怎么办?在传参的时候强制类型转换?那岂不是很麻烦,每当使用这个函数的时候,只要不是char类型的指针都需要强制类型转换。那么,有没有一种一劳永逸的做法?肯定是有,将函数的参数设置成void型,就万事大吉了。只需要在函数实现的内部强制类型转换。
2).内部强制类型转换需要注意的问题
首先应该知道在32位平台上,int型占4字节,float型占4字节,char型占1字节,double型占8字节。那么在函数内部强制类型转换的时候应该转换成什么型呢?
看一个小程序:
void* my_memmove(void* p1, void* p2, size_t count)
{
assert(p1);
assert(p2);
double *dest = (double *)p1;
double *src = (double *)p2;
if ((dest > src) && (dest < src + count))
{
while (count--)
{
*(dest + count) = *(src + count);
}
}
else
{
while (count--)
{
*dest = *src;
dest++;
src++;
}
}
return p1;
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int i = 0;
my_memmove(arr + 4, arr + 2, 16);
for (i = 0; i < 10; i++)
{
printf("%d\n", arr[i]);
}
system("pause");
return 0;
}
当把传进来的参数强制转化为double 程序出现奔溃。试着分析一下。
(1).在内存中数组arr是以4个字节存储,但是在内存拷贝的时候是以8个字节为单位拷贝,说的直白一点就是,要把数组中第一个和第二个元素(1和2)拷贝到8个字节中,那么在输出的时候是用四个字节输出的。输出的内容就是
我们会发现输出的并不是我们想要的。我们要的是 1 2 3 4 3 4 5 6 9 10.
(2)那么用强制转换成什么类型最合适?
不难发现,让指针转换成char类型不会出错。原因就不再啰嗦了。
三.程序为什么分为两种情况?
1).一种情况是从后向前拷贝,一种是从前向后拷贝。
2).试着分析
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; my_memmove(arr + 4, arr + 2, 16); 从前向后拷贝的时候,3放在5的位置,4放在6的位置,该拷贝5的时候,5已经变成了3.和我们的初衷不一样,所以引入了从后向前拷贝的情况。
[b]以上就是本人在学习过程中的一些经验总结。当然,本人能力有限,难免会有纰漏,希望大家可以指正。[/b]
本文出自 “做一个小小小司机” 博客,请务必保留此出处http://10799170.blog.51cto.com/10789170/1715206
相关文章推荐
- 网络基础(5)- 传输层和应用层的协议和作用
- 计算机网络基础(五)——传输层和应用层
- 计算机网络基础知识--TCP/IP协议、IP分组、TCP传输
- 基础计算机网络——应用层(Application Layer)笔记
- 基础计算机网络——传输层(Transport Layer)笔记
- 计算机网络基础--应用层
- 计算机网络教程-传输层(十一)传输层基础协议:简单协议与停止-等待协议
- 计算机网络基础--传输层
- 计算机网络应用层和传输层及网络层协议有哪些?
- 计算机网络教程-应用层(七)客户-服务器模式、套接字、使用传输层的服务(tcp、udp)
- 计算机网络:传输层(TCP/UDP) 应用层(HTTP) 知识总结
- 【Android应用开发技术:网络通信】计算机网络基础
- 计算机网络基础之OSI七层参考模型(二、应用层、表示层、会话层)
- 计算机网络基础【应用层】——域名系统DNS
- 计算机网络基础之OSI七层参考模型(三、传输层、网络层、数据链路层、物理层)
- 计算机网络基础_1_物理层与数据链路层的作用
- 计算机网络基础_3_网络层的作用(下) --ICMP和ARP的工作原理
- 运维之基础网络篇-----5.传输层 、 应用层
- (5.1.6)计算机网络基础之应用层
- 计算机网络(二) --- 网络基础 : 传输方式的分类及网络的构成要素