c++学习之路(1)—–基本数据类型

  • Post author:
  • Post category:其他




一、基本类型



1、预定义类型

包含:整型、字符型、布尔型、浮点型、空类型,指针类型。



1.1整型

c++有四种整型类型:short、int、long、long long,每种都有signed(有符号,默认)、unsigned(无符号)两种分类,有符号整数既可以表示非负整数,又可以表示负整数;但是,无符号整数不能表示负数,只能表示非负整数。

在c++的实现中,每一种类型在不同系统上使用的存储位数(宽度)是不同的,其规则为:

● short至少16位

● int至少与short一样长

● long至少32位,且至少与int一样长

● long long至少64位,且至少与long一样长



1.2字符型

类型 大小
char 8位(即可表示28个字符)
wchar_t 16位
char16_t 16位
char32_t 32位



1.3布尔类型

当表达式需要一个算术值时 布尔对象和布尔文字都被隐式地提升成 int(正 如下面的例子) false 变成 0 而 true变成1,bool类型不确定大小



1.4浮点型

类型 大小 位数
float 32为单精度浮点数 7
double 64位双精度浮点数 15/16



1.5空类型

关键字 void



1.6指针类型

<类型>* <指针变量>;



2、自定义数据类型

包含:数组、结构体(struct)、联合体(union)、枚举(enum)



2.1数组类型

int a[100]={1,2,3};//一维数组
int a[2][3]={{1,2,3},{4,5,6}}



2.1结构体类型

struct 名称{
  数据类型 变量名1;
   数据类型 变量名2;
   。。。。
   数据类型 变量名n;
 }结构体变量名;
 struct Info{
   int age;
   char name[32];
}info[SIZE];



2.2联合体类型

共用内存

union 名称{
  数据类型 变量名1;
   数据类型 变量名2;
   。。。。
   数据类型 变量名n;
 };



2.3枚举类型

enum 枚举名{
     标识符[=整型常数],
     标识符[=整型常数],
...
    标识符[=整型常数]
} 枚举变量;



二、类与对象



2.1类的声明与对象的存储

#include <iostream>
using namespace std;

//类通常定义在函数外面
class Student{
public:
    //类包含的变量
    char *name;
    int age;
    float score;
    //类包含的函数
    void say(){
        cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl;
    }
};

int main(){
    //创建对象
    Student stu;//创建栈对象
    stu.name = "小明";//创建对象以后,可以使用点号.来访问成员变量和成员函数,这和通过结构体变量来访问它的成员类似,如下所示:
    stu.age = 15;
    stu.score = 92.5f;
    stu.say();
    Student *pStu = new Student;//创建堆对象必须用指针指向匿名对象
    return 0;
}

栈内存是程序自动管理的,不能使用 delete 删除在栈上创建的对象;堆内存由程序员管理,对象使用完毕后可以通过 delete 删除。在实际开发中,new 和 delete 往往成对出现,以保证及时删除不再使用的对象,防止无用内存堆积。

有了对象指针后,可以通过箭头->来访问对象的成员变量和成员函数

pStu -> name = "小明";
pStu -> age = 15;
pStu -> score = 92.5f;
pStu -> say();
class Student{
private:  //私有的
    char *m_name;
    int m_age;
    float m_score;
public:
    //成员变量
    char *name;
    int age;
    float score;

    //成员函数
    void say();  //函数声明 自动加入inline
};

//函数定义//需要先在类体中定义函数名称,可以再外卖重新定义实现
void Student::say(){
    cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl;
}

在类体中直接定义函数时,不需要在函数名前面加上类名,因为函数属于哪一个类是不言而喻的。

但当成员函数定义在类外时,就必须在函数名前面加上类名予以限定。::被称为域解析符(也称作用域运算符或作用域限定符),用来连接类名和函数名,指明当前函数属于哪个类。

成员函数必须先在类体中作原型声明,然后在类外定义,也就是说类体的位置应在函数定义之前。

在类体中定义的成员函数会自动成为内联函数,在类体外定义的不会。当然,在类体内部定义的函数也可以加 inline 关键字,但这是多余的,因为类体内部定义的函数默认就是内联函数。

私有成员变量大都以m_开头,这是约定成俗的写法,不是语法规定的内容。以m_开头既可以一眼看出这是成员变量,又可以和成员函数中的形参名字区分开。

对象创建分别为每个对象的成员变量分配内存,但是所有对象都共享同一段函数代码。对象的大小只受成员变量的影响,和成员函数没有关系。成员函数在代码区分配内存,而不是在栈区。

对象的内存中只保留了成员变量,除此之外没有任何其他信息,程序运行时不知道 stu 的类型为 Student,也不知道它还有四个成员函数 setname()、setage()、setscore()、show(),C++ 究竟是如何通过对象调用成员函数的呢?

C++函数的编译

C++和C语言的编译方式不同。C语言中的函数在编译时名字不变,或者只是简单的加一个下划线_(不同的编译器有不同的实现),例如,func() 编译后为 func() 或 _func()。

而C++中的函数在编译时会根据它所在的命名空间、它所属的类、以及它的参数列表(也叫参数签名)等信息进行重新命名,形成一个新的函数名。这个新的函数名只有编译器知道,对用户是不可见的。对函数重命名的过程叫做名字编码(Name Mangling),是通过一种特殊的算法来实现的。

Name Mangling 的算法是可逆的,既可以通过现有函数名计算出新函数名,也可以通过新函数名逆向推演出原有函数名。Name Mangling 可以确保新函数名的唯一性,只要函数所在的命名空间、所属的类、包含的参数列表等有一个不同,最后产生的新函数名也不同。这样通过传递对象指针就完成了成员函数和成员变量的关联。这与我们从表明上看到的刚好相反,通过对象调用成员函数时,不是通过对象找函数,而是通过函数找对象。



2.2构造函数与析构函数

类体中有两个成员构造函数(Constructor)和析构函数(Destructor),

构造函数的名字和类名相同



而析构函数的名字是在类名前面加一个~符号

。有了构造函数在创建对象的同时为成员变量赋值。

构造函数:

class Student{
private:
    char *m_name;
    int m_age;
    float m_score;
public:
    //声明构造函数
    //采用初始化列表
Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){
    //TODO:
}//:相当于赋值

    Student(char *name, int age, float score);//为名称命名
    ~Student()//声明普通成员函数
    void show();
};

构造函数也可以重载,可以使用初始化列表,在初始化列表中成员变量的赋值顺序由它们在类中的声明顺序决定,初始化 const 成员变量的唯一方法就是使用初始化列表。

析构函数是没有参数,编译器会自动添加,也可以主动写上去.

new 创建的对象位于堆区,通过 delete 删除时才会调用析构函数;如果没有 delete,析构函数就不会被执行。

成员函数中可以使用this,并且这个类实例化以后可以使用



2.3静态变量和静态成员函数

静态变量需要在类体之外赋值,没有初始化不能使用

访问静态变量

//通过类类访问 static 成员变量
Student::m_total = 10;
//通过对象来访问 static 成员变量
Student stu("小明", 15, 92.5f);
stu.m_total = 20;
//通过对象指针来访问 static 成员变量
Student *pstu = new Student("李华", 16, 96);
pstu -> m_total = 20`

注意:static 成员变量不占用对象的内存,而是在所有对象之外开辟内存,即使不创建对象也可以访问

普通成员函数可以访问所有成员(包括成员变量和成员函数),静态成员函数只能访问静态成员和静态成员函数



2.3常对象和常成员函数

const class *p = new class(params);

class const *p = new class(params);

常对象定义方法

class Student{
public:
    Student(char *name, int age, float score);
    void show();
    //声明常成员函数
    char *getname() const;
    int getage() const;
    float getscore() const;//常成员函数关键字
private:
    char *m_name;
    int m_age;
    float m_score;
};
Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ }
void Student::show(){
    cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<endl;
}
//定义常成员函数
char * Student::getname() const{
    return m_name;
}
int Student::getage() const{
    return m_age;
}
float Student::getscore() const{
    return m_score;
}

需要强调的是,必须在成员函数的声明和定义处同时加上 const 关键,只能调用常对象成员(常变量和常函数)



2.4友元

借助关键字友元(friend),可以使得其他类中的成员函数以及全局范围内的函数访问当前类的 private 成员。



三、指针与引用



四、封装继承多态



五、模板与容器与STL



六、文件操作与输入输出



七、异常处理



八、第三方库boost



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