遇到的库函数
void *memcpy(void*destin, const void *src, size_t n);
功能
由src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内。
头文件
#include<string.h>
返回值
函数返回一个指向dest的指针。
htons()–“Host to Network Short”
htons是将整型变量从主机字节顺序转变成网络字节顺序, 就是整数在地址空间存储方式变为高位字节存放在内存的低地址处。
CStringLeft(intnCount)const; //从左边1开始获取前 nCount个字符
CStringMid(intnFirst)const; //从左边第 nCount+1个字符开始,获取后面所有的字符
CStringMid(intnFirst,intnCount)const; //从左边第 nFirst+1 个字符开始,获取后面nCount个字符
CStringRight(intnCount)const; //从右边1开始获取从右向左前 nCount个字符
voidMakeUpper(); //这个函数可以将CString字符转化为一个大写的字符串。
用法实例:
CString a,b;
a = "123456789";
b =a.Left(4); //值为:1234
b =a.Mid(3); //值为:456789
b = a.Mid(2, 4); //值为:3456
b = a.Right(4); //值为:6789
要实现把一个QString转换为char *,一般遵循这样的步骤:
第一步,对该QString对象调用QString的toLatin1()方法,以获得该字符串的latin1值。
注意toLatin1()的原型如下:QByteArray QString::toLatin1 () const
它将返回一个QByteArray。
示例:
QString qstr = “convert”
QByteArray ba = qstr.toLatin1();
第二步,对第一步得到的QByteArray对象调用data()方法,以获得指向存储于这个数组中数据的指针。
示例:
const char *cstr = ba.data();
完整的例子:
QString str;
str.toLatin1().data();//即可获得指向存储于该char类型数据的指针
QString comName = QString(“%1%2”).arg(str).arg(comIndex);
//表示的是str放在%1的位置,comIndex放在%2的位置,(%1,%2作为占位符)两个参数连着一起组成了comName。
QString jd = QString(“%1”).arg(jd_m);
//表示jd_m精确到小数点后一位存放到jd 。
sprintf(地址,”%nd”,整型变量)//表示将整型变量发送至地址开始的n个内存段,n表示存放到从地址开始的n个内存段
例如:整型变量为1234,则应该为sprintf(&buf,”%4d”,1234)//表示将1234按照字符型输入到&buf开始的内存中,执行后,buf的内存段为’1’,’2’,’3’,’4’
sscanf() 的作用:从一个字符串中读进与指定格式相符的数据.
原型: int sscanf (const char
str,const char
format,……..);
说明: sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。转换后的结果存于对应的参数内。
成功则返回参数数目,失败则返回0。
例如:sscanf((char *)data[0], “%d”, &buf);//表示将data[0]的数据转化成整型输入到&buf开始内存中
emit是发出信号 对应的是接收信号
在这之前 应该有QObject::connect(*FindDialog, SIGNAL(), *receiver, SLOT()) 类似的句子
调用emit ..后,对应的SLOT里面的函数就会被调用
例如:
在某处有emit SpaceKeyPressed();
在某处还有connect(InputCMD_LineEdit,SIGNAL(SpaceKeyPressed()),this,SLOT(ShowFuncList()))
//< 那么就是向外发出SpaceKeyPressed信号,调用 connect(InputCMD_LineEdit,SIGNAL(SpaceKeyPressed()),this,SLOT(ShowFuncList()));中的ShowFuncList()函数
函数功能是把文件指针指向文件的开头,需要包含头文件stdio.h
fseek
函数名: fseek
功 能: 重定位流上的文件指针
用 法: int fseek(FILE *stream, long offset, int fromwhere);
描 述: 函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere为基准,偏移offset个字 节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。
返回值: 成功,返回0,否则返回其他值。
引用的难点
1、函数返回值是引用(引用当左值)
当函数返回值为引用时
若返回栈变量
不能成为其它引用的初始值
不能作为左值使用
错误用例如下:
main()
{
int &res;
res = getAA2();
cout << res << endl;//会返回乱码。因为此时10的内存空间已经被释放,如果res是引用,因为返回的内存空间已经被编译器回收了,所以是乱码
}
int& getAA2()
{
int a;
a = 10;
return a;
}
2、若返回静态变量或全局变量
可以成为其他引用的初始值
即可作为右值使用,也可作为左值使用
//下例中即是
函数返回值是引用,并且当右值
main()
{
int &res;
res = getAA2();
cout << res << endl;//会正常返回,因为内存空间没有释放掉
}
int& getAA2()
{
static int a = 10;
return a;
}
3、返回变量的值和返回变量本身(
函数返回值是引用,并且当左值
)
int get();//返回变量的值---->此种情况不允许左赋值
int& get()//返回变量本身--->此种情况允许左赋值get() = 100;//此时a=100
{
static a = 10;
return a;
}
运算符重载
一、二元运算符重载(+、-)
1、全局函数完成 +操作符重载
Complex operator+(Complex &c1, Complex &c2)//全局函数+运算符重载实现
{
Complex tmp(c1.a+ c2.a, c1.b + c2.b);
return tmp;
}
调用:Complex c3 = c1 + c2;
其中,Complex是定义的新类
class Complex
{
private:
int a;
int b;
friend Complex operator+(Complex &c1, Complex &c2);全局函数+运算符重载声明
friend Complex& operator++(Complex &c1); //全局前置++运算符重载声明
friend Complex& operator++(Complex &c1, int)//全局后置++运算符重载声明
friend ostream& operator<<(ostream &out, Complex &c1);//全局<<运算符重载声明
public:
Complex(int a=0, int b=0)
{
this->a = a;
this->b = b;
}
public:
Complex operator-(Complex &c2)//成员函数-运算符重载实现
{
Complex tmp(this->a - c2.a, this->b - c2.b);
}
Complex& operator--()//成员函数前置--运算符重载实现
{
this->a--;
this->b--;
return *this;
}
Complex& operator--(int)//成员函数后置--运算符重载实现,int为占位符,用于区分前置--
{//先赋值再运算
Complex tmp = *this;
this->a --;
this->b --;
return tmp;
}
public:
void printCom()
{
cout<<a<<" + "<<b<<"i "<<endl;
}
private:
};
2、类成员函数完成-操作符重载
Complex operator-(Complex &c2)
3、
全局函数、类成员函数方法实现运算符重载步骤
1)
要承认操作符重载是一个函数
,写出函数名称operator+ ()
2)
根据操作数,写出函数参数
3)
根据业务,完善函数返回值(看函数是返回引用 还是指针 元素),及实现函数业务
//通过全局函数方法完成+操作符重载
//函数声明friend型见上面的类 Complex operator+(Complex &c1, Complex &c2)
//具体实现
Complex operator+(Complex &c1, Complex &c2)
{
Complex c3;
c3.a = c1.a + c2.a;
c3.b = c1.b + c2.b;
return c3;
}
//函数调用
int main()
{
Complex c1(1, 2), c2(3, 4);
Complex c3 = c1 + c2;
c3.printCom();
}
//通过类成员函数完成-操作符重载
//函数声明和实现见上面的类 Complex operator-(Complex &c2)
//函数调用
int main()
{
Complex c1(1, 2), c2(3, 4);
Complex c4 = c1 - c2;
c4.printCom();
}
二、一元运算符重载(前后置++、- -)
//前置++操作符 用全局函数实现
Complex& operator++(Complex &c1)
{
c1.a ++;
c1.b ++;
return c1;
}
//声明为friend型(因为要用到其类的私有变量) 见前面的类
//调用
main()
{
Complex c1(1, 2)
++c1 ; //=需要写出操作符重载函数原形
c1.printCom();
}
//后置++操作符 用全局函数实现
Complex& operator++(Complex &c1, int) //其中int为占位符,用于区分前置++
{
Complex tmp = c1;
c1.a ++;
c1.b ++;
return tmp;
}
//声明为friend型(因为要用到其类的私有变量) 见前面的类
//调用
main()
{
Complex c1(1, 2);
c1 ++; //系统会识别是后置++,自动调用后置++重载
c1.printCom();
}
//前置--操作符 成员函数实现
具体实现见上面的类
//调用
main()
{
Complex c1(1, 2);
--c1;
c1.printCom();
}
//后置--操作符 成员函数实现
具体实现见上面的类
//调用
main()
{
Complex c1(1, 2);
c1 --;
c1.printCom();
}
三、输入输出流重载只能够用全局函数(友元函数)实现(因为无法知道ostream类的源码,就无法用成员函数实现)
//实现
ostream& operator<<(ostream &out, Complex &c1)
{
out<<c1.a<<" + "<<c1.b<<"i "<<endl;
return out;
}
//调用方法
cout<<c1;
四、C++函数规定不能用友元函数重载的运算符有= () [] ->.
五、重载赋值运算符=
1 先释放旧的内存
2 返回一个引用
3 =操作符 从右向左
//具体实现
Name& operator=(Name &obj1)
{
//1 先释放obj3旧的内存
if (this->m_p != NULL)
{
delete[] m_p;
m_len = 0;
}
//2 根据obj1分配内存大小
this->m_len = obj1.m_len;
this->m_p = new char [m_len+1];
//3把obj1赋值给obj3
strcpy(m_p, obj1.m_p);
return *this;
}
//涉及到的类Name
class Name
{
public:
Name(char *pN);
Name(const Name*);
Name& operator=(Name &obj1);
~Name();
protected:
char *pName;
int size;
};
//应用
void main()
{
Name obj1("ZhangSan");
Name obj2 = obj1;
Name obj3("NoName");
obj3 = obj2 = obj1;
}
六、函数指针
int add(int a, int b)
{
return a+b;
}
int main()
{
typedef int (MyFuncType)(int a, int b);
MyFuncType *myPointerFunc = NULL;
myPointerFunc = &add;//myPointerFunc即为函数指针
myPointerFunc(3, 4);//间接调用
}