C++学习入门笔记II

  • Post author:
  • Post category:其他


遇到的库函数


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);//间接调用
}



版权声明:本文为dazhushenxu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。