重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
使用memcpy即可, 比如你另外建立一个结构体sortbook[1000]用来保存排序结果,将book中的第i个元素赋值到sortbook的第j个元素中
成都创新互联是一家专业提供朝天企业网站建设,专注与网站设计、网站建设、H5技术、小程序制作等业务。10年已为朝天众多企业、政府机构等服务。创新互联专业网站建设公司优惠进行中。
memcpy(sortbook[j], book[i], sizeof(struct book));
用这个函数需要#include string.h
函数原型
void *memcpy(void*dest, const void *src, size_t n);
功能
由src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内。
头文件
#includestring.h
返回值
函数返回一个指向dest的指针。
说明
1.source和destin所指内存区域不能重叠,函数返回指向destin的指针。
2.与strcpy相比,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。
memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;
例:
char a[100], b[50];
memcpy(b, a,sizeof(b)); //注意如用sizeof(a),会造成b的内存地址溢出。
strcpy就只能拷贝字符串了,它遇到'\0'就结束拷贝;例:
char a[100], b[50];
strcpy(a,b);
3.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。
//注意,source和destin都不一定是数组,任意的可读写的空间均可。
位拷贝也叫浅拷贝。。。是编译器帮你自动生成的拷贝构造函数做的事情,它只能做一些基本的赋值操作,如果自己定义拷贝构造函数就要防止位拷贝。。因为位拷贝容易发生一些错误。。
class CStr
{
public:
CStr(); //默认构造函数
CStr(const char* psz); //一种广义拷贝构造函数
CStr(const CStr str); //拷贝构造函数
const CStr operator=(const CStr str); //赋值构造函数
size_t GetSize() const; //这里的const是什么意思?它必须吗?
operator const char*() const { return m_pdata; }
protected:
const CStr* _Copy(const CStr str);
private:
char* m_pdata;
size_t m_size;
};
CStr::CStr()
{
m_pdata = NULL;
m_size = 0;
}
size_t CStr::GetSize() const
{
return m_size;
}
const CStr* CStr::_Copy(const CStr str)
{
if(this != str)
{
if(m_pdata){
delete[] m_pdata;
}
m_size = str.GetSize();
m_pdata = new char[m_size + 1]; assert(m_pdata);
strcpy(m_pdata, str);
}
return this;
}
CStr::CStr(const char* psz) : m_pdata(NULL), m_size(0)
{
assert(psz);
if(m_pdata != psz)
{
if(m_pdata){
delete[] m_pdata;
}
m_size = strlen(psz);
m_pdata = new char[m_size + 1]; assert(m_pdata);
strcpy(m_pdata, psz);
}
}
CStr::CStr(const CStr str): m_pdata(NULL), m_size(0)
{
_Copy(str);
}
const CStr CStr::operator=(const CStr str)
{
return *(_Copy(str));
}
int main()
{
const char* psz = "test";
const char* psz1 = "me";
CStr str(psz); //拷贝构造函数,此处调用的是CStr(const char* psz)。 #1
CStr str2(str); // 拷贝构造函数,此处调用的是 CStr(const CStr str) #2
CStr str1 = psz1; // 拷贝构造,str1此前并不存在,现在要先构造它。 #3
str = str1; // 真正的赋值构造函数 #4
return 0;
}
上面这个小型的例子,主要就是为了阐述赋值构造函数与拷贝构造函数之间的区别,其实,赋值构造函数不应该被称为一个构造函数,充其量只能算得上一个重载的操作符函数。
在C语言中,我们知道"=="是判等操作符,而"="却是一个赋值操作符,所以只要没有出现"="操作符,也就不会有赋值操作可言。
在调用赋值构造函数的时候,类对象已经存在,自然谈不上构造类对象,它只是对该已经存在的类对象的成员变量进行修改(所谓的赋值)操作。而拷贝构造函数是利用一个已经存在的类对象构造出一个新的类对象。
回到上面的例子,相信大多数人都应该能分清#1、#2、#4所调用的函数,而对于#3,赋值构造的实际用意是修改一个已有的对象,而现在str1还没有被定义,所以此处还是必须要调用拷贝构造函数先产生一个CStr对象。
最后,定义与赋值同时进行的话,必须要先定义,所以必须得先调用拷贝构造函数,而对于符合单纯的赋值操作语法的语句(也就是只有两个操作数的表达式)来说,才是真正的调用赋值构造函数。
如果定义了拷贝构造函数,在赋值操作时就会调用该拷贝构造函数,如定义了Class CTest,然后使用CTest A,CTest B=A时就会调用CTest类的拷贝构造函数。需要注意的是,和默认构造函数不同,只要用户没有定义自己的拷贝构造函数,编译器就会提供一个默认的拷贝构造函数,该函数的作用是将源对象的数据成员的取值复制到新生成的目标对象中。但是值得注意的是,编译器提供的拷贝构造函数和赋值运算符函数的默认实现都是一个浅层的拷贝操作!即模拟C语言中struct的拷贝和赋值操作,只拷贝对象中数据成员的取值,而不管某个数据成员是否还引用了其它的数据。
1、首先C语言没办法实现构造函数和析构函数,因为C语言是面向过程的语言,没有定义面向对象的class概念。C++语言是以C语言为基础扩展出来的一种编程语言,它在继承了C语言的基础上,增加了面向对象的编程方法,其中就包含了class。
2、如果你所描述的c语言是指C++语言,那么是可以自已定义并实现CString类的一些功能。因为CString类是微软VC++ MFC实现的基础类,而非C++标准类库,所以CString类定义中使用了一些AFX函数,依赖于MFC环境,所以想自定义一个完全取代CString的类很困难,也无意义。
3、如果只是需要学习CString的构造函数、析构函数及赋值函数,可以参考MFC类库源文件:
\MICROSOFT VISUAL STUDIO\VC98\MFC\Include\AFX.INL
\MICROSOFT VISUAL STUDIO\VC98\MFC\SRC\STRCORE.CPP
\MICROSOFT VISUAL STUDIO\VC98\MFC\SRC\WINSTR.CPP