我是靠谱客的博主 自然信封,最近开发中收集的这篇文章主要介绍C++基础讲解第一期(超详细)一、面向对象概述二、C到C++的过度,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

C++基础讲解第一期 代码中也有对应知识注释,别忘看

  • 一、面向对象概述
    • 1、C++发展
    • 2、为什么要学习C++
    • 3、面向对象和面向过程
    • 4、C++与C语言相比的改进
    • 5、面向对象的三要素(中心思想)
  • 二、C到C++的过度
    • 1、第一个代码
    • 2、作用域限定符(::)
    • 3、命名空间
      • a)目的:
      • b)使用
    • 4、C++的输入和输出
    • 5、register关键词
    • 6、struct的加强
    • 7、bool类型
    • 8、c与c++中三目运算符的不同
    • 9、c/c++中的const:
    • 10、C++引用
      • a)概念:
      • b)使用
    • 11、引用的本质:常指针
    • 12、引用作为函数的返回值
    • 13、指针引用
    • 14、常引用
    • 15、内联函数
    • 16、c++中的默认参数
    • 17、占位参数
    • 18、函数重载(重点)
    • 19、c++的动态内存分配
    • 20、多维数组的创建和释放

一、面向对象概述

1、C++发展

1998开始,c++98—>c++03—>c++11—>c++14

2、为什么要学习C++

众所周知,c++是一门面向对象的语言,在世界上的地位非常高,使用非常广泛,就业前景好。c++是c语言的升级版,c++几乎完全兼容c语言。

应用范围:应用软件开发、游戏开发、多媒体开发、人工智能、底层驱动、图形界面。

3、面向对象和面向过程

C语言:面向过程,以过程为中心,强调做算法,特点就是以函数为单位。数据从一个函数流向另一个函数。

C++:面向对象,是以事务为中心的编程,封装一个个的类,维护的代码期待更少。

4、C++与C语言相比的改进

C++是从C语言演化而来,C语言是过程式编程语言,以过程为中心,以算法为驱动。而C++是面向对象的编程方式,以对象为中心,以消息为驱动的编程方式,这是C++在C语言上的最大改进。

5、面向对象的三要素(中心思想)

封装:把一类事物抽象封装成类,并且可以把自己的类中的数据和函数只让可信的类或者对象操作。对不可暴露的接口进行隐藏。

继承:所谓继承,就是指类和类之间的关系,一个类可以继承另一个类

多态:多种形态,简单的说就是一个接口,多种方法,程序在运行的时候,才决定调用哪个函数。

二、C到C++的过度

1、第一个代码

#include<iostream>//C++标准输入输出流
using namespace std;//声明标准命名空间

int main(){
    cout<<"hello world!"<<endl;//cout:标准输出函数     <<:输出运算符 endl:换行 
}

2、作用域限定符(::)

#include<iostream>
using namespace std;

int num = 100;

int main(){
    int num = 999;
    cout<<"num ="<<num<<endl;//不加作用域运算符,因为在局部变量作用域中 所以输出的是局部变量num的值
    //::作用域限定符,主要用于操作全局变量或者类或者函数
    cout<<"num2 = "<<::num<<endl;//加上作用域运算符 输出的就是全局变量num

    return 0;
}

3、命名空间

a)目的:

为了解决多个小组合作开发时,或者不同代码段之间命令冲突的问题,C++引入了命名空间的概念。
在这里插入图片描述

b)使用

1)语法

namespace Li
{
	//变量、函数、类、宏定义等等
}

2)使用

#include<iostream>
/*命名空间:
    命名空间里面几乎可以存放所有的全局的东西
    例如:全局变量,函数,结构体,类,宏定义等
  定义一个命名空间
    注意:定义之后不需要加;
        内部变量空间已经开辟,不只是定义数据类型
*/
using namespace std;

namespace zhangsan     //命名空间zhangsan
{
    int num = 333;
    void fun()
    {
        cout<<"hello zhangsan"<<endl;
    }
}

namespace Lisi         //命名空间Lisi
{
    int num = 888;
    void fun()
    {
        cout<<"hello Lisi"<<endl;
    }
}

void test()//命名空间使用方法一
{
    cout<<"zahngsan的num = "<<zhangsan::num<<endl;
    cout<<"lisi的num = "<<Lisi::num<<endl;
    zhangsan::fun();
    Lisi::fun();
    //使用时都要在变量前加上命名空间和作用域限定符 来确定是哪一个变量
}

void test2()//命名空间使用方法二
{
    using zhangsan::num;
    //using Lisi::num;     不能同时对同名的其他命令空间的成员进行声明
    cout<<"zhangsan的num = "<<num<<endl;
    num = 1000;//将zhangsan中的num修改为1000
    cout<<"zhangsan的num = "<<num<<endl;

    cout<<"Lisi的num = "<<Lisi::num<<endl;
    //使用lisi的num还和方法一一样 因为没有声明lisi的命名空间
}

//使用命名空间方法三
using namespace zhangsan;//与使用using namespace std 相同 先声明
void test3()
{
    cout<<num<<endl;
}

int main(){
    //test();
    //test2();
    test3();

    return 0;
}

4、C++的输入和输出

输入:cin
输出:cout

#include<iostream>
using namespace std;

void test1(){
    int a = 333;
    char b = 'w';
    char c[] = "hello";
    float d = 3.1415926;

    cout<<"a = "<<a<<endl;
    cout<<"b = "<<b<<endl;
    cout<<"c = "<<c<<endl;
    cout<<"d = "<<d<<endl;
}

void test2(){
    int a,b,c;
    cin>>a>>b>>c; //cin:标准输入函数   >>:输入运算符
    cout<<"a = "<<a<<endl;
    cout<<"b = "<<b<<endl;
    cout<<"c = "<<c<<endl;
}

int main(){
    //test1();
    test2();

    return 0;
}

5、register关键词

register关键词的作用:请求编译器让变量存放在寄存器里面,以提升变量的访问速率。

C语言:register关键词修饰的变量不可以用&操作符取地址。内存的最小单位是字节,我们对内存的每个字节进行编号,这个编号就是我们所说的地址,寄存器不在内存之中,所以不能对其取地址。

C++:可以对一个寄存器变量取地址,但register对变量的声明变得无效,被定义的变量将会强制保存在内存中。

#include<iostream>
using namespace std;

int main(){
    register int i = 0;//声明一个寄存器变量,不能取地址
    register int j = 0;

    for(i = 0;i < 10000;i++){
        for(j = 0;j < 10000;j++){

        }
    }
    cout<<"运行结束"<<endl;

    return 0;
}

6、struct的加强

C++中的结构体

#include<iostream>
using namespace std;

int main(){
    register int i = 0;//声明一个寄存器变量,不能取地址
    register int j = 0;

    for(i = 0;i < 10000;i++){
        for(j = 0;j < 10000;j++){

        }
    }
    cout<<"运行结束"<<endl;

    return 0;
}

7、bool类型

C语言中想要判断“真”和“假”,只能用0和1来表示,这点在c++中加以改进,引入了两个新的关键词true和false

bool类型用法:
1.占一个字节
2.bool类型只有两个取值----true和false(编译器内部分别用1和0表示)
3.用途:推荐使用bool类型表示逻辑运算,关系运算以及开关变量的值。

#include<iostream>

using namespace std;

int main(){
    bool a = true;
    cout<<"a = "<<a<<endl;

    bool b = false;
    cout<<"b = "<<b<<endl;

    bool c = -1;
    cout<<"c = "<<c<<endl;
    cout<<"sizeof(bool) = "<<sizeof(bool)<<endl;

    return 0; 
}

8、c与c++中三目运算符的不同

c语言:三目运算符返回的是变量的值
c++:三目运算符返回的是变量本身(可以作为左值使用)

#include<iostream>

using namespace std;

int main(){
    int a = 1,b = 0;
    int num = (a > b) ? a : b;
    cout<<"num ="<<num<<endl;

    (a < b) ? a : b = 100;
    cout<<"b = "<<b<<endl;

    return 0;
}

9、c/c++中的const:

(1)区别:
c语言:const修饰的是只读变量,但是可以通过修改地址来修改其值,不可以通过变量来修改。
c++:真正的常量,const常量会被编译器放入符号表中,类似于宏,不占用内存,符号表存储的是一系列键值对,编译器不会为const常量分配空间,但是我们对一个常量进行取地址时,操作系统会分配一段内存,并且用常量来填充。
在这里插入图片描述

#include<iostream>
using namespace std;

int main(int argc, char const *argv[])
{
    const int a = 1;//c++中,const修饰的是常量,放在符号表
    int *p = (int *)&a;//对const修饰的常量取地址,编译器会分配一段内存空间,存储常量的值
    *p = 2;//并不会改变a的值,*p会开辟一段新的空间用来存放2
    printf("a = %d,*p = %dn",a,*p);//a还是1,p是2
    return 0;
}
const和#define的区别:
1.const有类型,可以进行编译器类型安全检查,#define无类型,不可进行类型检查
2.const有作用域,而#define不太重视作用域,作用域默认是从定义到文件结尾,如果定义在指定作用域下有效的常量,那么#define就不能用

10、C++引用

a)概念:

c++提供了给变量取别名的机制,那就是引用,引用是c++相对于c的扩充。
注意:typedef是对类型取别名,不能对变量进行重命名。

b)使用

引用的定义方式类似于指针,只是用&取代了*,语法格式:

&:在定义的时候表示引用
type &name = data;//其实就是将变量data取别名为name
#include<iostream>
using namespace std;

//传引用,引用作为函数参数,将实参和形参绑定在一起,指向用一份数据
void swap(int &x,int &y){//在c语言中 我们是定义的指针 传参传的是地址 而使用引用就不需要这样了
    int temp = x;
    x = y;
    y = temp;
}
int main(int argc, char const *argv[])
{
    int a = 100,b = 200;
    cout<<"a = "<<a<<"b = "<<b<<endl;
    swap(a,b);
    cout<<"a = "<<a<<"b = "<<b<<endl;


    int &c = a;//使用引用必须初始化
    c = 1000;
    cout<<"a = "<<a<<endl;
    //int &d = 100;  //不能用常量初始化引用
    return 0;
}

11、引用的本质:常指针

1.本质

int &name = var; --------->int *const name = &var;
//当使用引用时不初始化,计算大小时,是当作指针来计算
//当初始化时,跟初始化的变量大小一致

从使用者角度看,引用会让人误以为只是一个别名,没有字节的存储空间,这其实是c++内部为了实用性而做的细节隐藏。

#include<iostream>
using namespace std;

struct test{
    int &a;//因为没有初始化,其相当于一个常指针,大小占8个字节
    int &b;
    char &c;
};

struct test1
{
    int a;
    int b;
    char c;
};

int main(){
    int a = 1;
    char c = 'c';
    int &pa = a;
    char &pc = c;

    cout<<sizeof(pa)<<endl;
    cout<<sizeof(pc)<<endl;
    cout << "test1 size = " << sizeof(test1) << endl;//结果是12,因为int占4个字节,占满了所以char也分配4个字节
    cout<<sizeof(test)<<endl;//结果是24,因为指针占8个字节,分析正常的语法现象时,当别名分析,分析奇怪的语法现象时,当常指针分析

    return 0;
}

12、引用作为函数的返回值

1)引用作为函数的返回值时,不能返回局部数据(局部变量,局部对象,局部数组)的引用,可以返回一个全局变量或者静态全局、局部变量的引用。
2)使用方式:
a)不接受返回值
b)用一个普通变量接收函数的返回值,这时接收的是变量的值而不是变量的引用
c)用一个引用来解释函数的返回值,接收的是一个引用
d)当作左值来使用

#include<iostream>
using namespace std;

int g = 100;

int& fun()//返回引用
{
    int x = 1;
    return g;//不能返回x,因为x是局部变量,为社么局部变量不能返回呢,因为我们说过引用必须初始化,当我们使用引用去接这个返回值时,其是一个局部变量,这时候其的生命周期已经结束,内存空间已经释放,那么引用就接不到,也就无法初始化,就错了
}

int main()
{
    fun();//不接收返回值
    int a = fun();//用一个普通变量接收返回的引用
    cout<<"a = "<<a<<endl;//a = 100,但是无法通过a去改变g的值

    int &b = fun();//用一个引用取接收函数的返回值,接收的就是一个引用
    b = 10000;
    cout<<"g = "<<g<<endl;

    fun() = 200; //当成左值使用,将200赋值给了g
    cout<<"g = "<<g<<endl; //g = 200
    cout<<"b = "<<b<<endl; //b = 200

    return 0;
}

13、指针引用

#include<iostream>
#include<string.h>

using namespace std;

struct student
{
    int id;
    char name[32];
};

void getmemory(student *&ptr)//使用指针引用 就不用传二级指针了
{
    ptr = (student *)malloc(sizeof(student));
    if(ptr == NULL){
        return;
    }
    ptr->id = 100;
    strcpy(ptr->name,"张三");
}

int main()
{
    student *ptr = NULL;
    getmemory(ptr);
    cout<<"id = "<<ptr->id<<" name = "<<ptr->name<<endl;

    return 0;
}

14、常引用

1)概论:所谓常引用,是指不能通过引用来改变引用对象的值。

定义:const Type &name = var;

2)使用方法:
常引用初始化方法有两种:
a)用一个普通变量去初始化常引用,例如:

int a;
const int &b = a;//b是a的常引用,a和b代表了同一块内存空间,但不能通过b去修改a的值

b)用常量初始化常引用,例如:

const int &num = 100;
#include<iostream>

using namespace std;

int main()
{
    int a = 1;
    const int &b = a;//变量初始化常引用
    //b = 200; 不可以通过b修改a的值
    a = 200; //可以通过a去修改a的值


    const int &pd = 200;//可以用常量初始化常引用,不是存在符号表之上,有内存空间
    //pd++; //不可以通过pd修改pd的值

    int *pc = (int *)&pd;
    (*pc)++;
    cout<<"pd = "<<pd<<endl;

    return 0;
}

15、内联函数

1)函数调用:有时间和空间的开销,程序在执行的过程中,需要做一些工作,将实参,局部变量,返回地址,以及若干寄存器变量压入栈中才能执行函数的代码,函数体中,代码执行完毕,还要清理现场,将之前压入栈的数据都出栈。

2)c语言中,可以使用宏函数来消除函数调用的时空开销,编译器通过复制宏代码,省去参数入栈,出栈等操作,但是宏函数存在一些安全隐患,但是在效率上还是可取的。
a>宏函数的缺陷:
在复制代码时,容易出现意想不到的边际效应,例如:

#define MAX(a,b) (a) > (b) ? a : b

执行语句

int i = 2, j = 1;
result = MAX(i,j) + 2;//其会被替换成 (i) > (j) ? i : j + 2, 其返回的是j + 2了,就错了

b>使用宏,无法调试
c>使用宏,无法访问类的私有成员

3)c++中,关于宏函数,推出了一种更高效的方式,就是使用内联函数,在编译阶段将函数体进行替换,类似于c语言中的宏展开,这种在函数调用处直接嵌入函数体的函数称为内联函数,也称为内置函数

4)内联函数的使用:

#include<iostream>
using namespace std;

inline int mymax(int a,int b)//只需要在函数定义处增加关键词inline即可
{
    return (a > b ? a : b);
}

int main()
{
    int i = 1,j = 2;
    int result = mymax(i,j);
    cout<<result<<endl;

    return 0;
}

5)内联函数的特点和限制
a)不能存在任何的循环语句
b)不能存在过多的条件判断语句
c)函数体不能过于庞大
d)不能对函数进行取地址操作
e)函数内联声明必须在调用语句之前

总结:
内联函数相对于普通函数,省去了函数调用时压栈出栈和返回等开销,因此,当函数体的开销远远大于压栈、出栈等开销时,内联函数将变得无意义。

16、c++中的默认参数

1)概念:
c++中,定义函数可以给形参指定一个默认值,在使用该函数时,如果没有给形参赋值,将使用这个值。

#include<iostream>
using namespace std;

int Add(int a,int b, int c = 0)
{
    return a + b + c;
}

int Bdd(int a = 1,int b = 3,int c = 0)
{
    return a + b + c;
}

//因为默认参数的定义顺序自左向右,如果设置了一个默认值,那么右边所有参数都要设置默认值
int Cdd(int a,int b = 3,int c = 4)
{
    return a + b + c;
}
int main()
{
    cout<<Add(1,2)<<endl;//第三个参数有了默认值,所以可以不用给形参赋值
    cout<<Add(1,2,3)<<endl;//当然也可以赋值,如果赋值就使用 我赋的这个值 默认值就不使用了

    cout<<Bdd(1,2)<<endl;//三个参数都要默认值,可以都不赋值

    //cout<<Cdd(1,2)<<endl;
    //使用错误,因为默认参数的定义顺序自左向右,如果设置了一个默认值,那么右边所有参数都要设置默认值
    
    cout<<Cdd(1)<<endl;

    return 0;
}

17、占位参数

1)概念:占位参数中有参数类型的声明,没有参数名的声明,一般情况下,在函数体内无法使用占位参数

#include<iostream>
using namespace std;

struct A
{
    unsigned int a:10;//a占10位
    unsigned int :22;//无名位域 占22位 没有名字 谁也使用不了
    unsigned int c:2;//c占2位
    //因为字节对齐 a分配了四个字节 32位 a占了10位
    //还有22位没有使用 无名位域正好占用22位,所以前两个一共四个字节
    //虽然c只占用2位 但由于字节对齐 其是int型 所以分配四个字节
    //这个结构体一共占用8个字节
};

void Add(int a,int b,int = 0)//一般占位参数和默认参数一起使用
{
    cout <<a + b<<endl;
}

int main(int argc, char const *argv[])
{
    Add(1,2);
    cout<<sizeof(A)<<endl;
    
    return 0;
}

18、函数重载(重点)

1)概念:
在实际开发中,有时候需要实现几个功能类似的函数,只是有些细节不同,c语言中需要设计多个函数,而函数的重载解决了这个问题。

2)重载的条件(重点)
a)函数名相同
b)函数的参数的个数或者类型或者参数的顺序不同(注意:常量不能作为重载的标准)
c)返回值类型不能作为重载的标准

#include<iostream>

using namespace std;

void Swap(int &a,double &b)
{
    cout<<"第一个"<<endl;
    int tmp = a;
    a = b;
    b = tmp;
}

void Swap(int &a,int &b)//参数的类型不同
{
    cout<<"第二个"<<endl;
    int tmp = a;
    a = b;
    b = tmp;
}

void Swap(int &a,double &b,int c)//参数的个数不同
{
    cout<<"第三个"<<endl;
    int tmp = a;
    a = b;
    b = tmp;
}

void Swap(double &b,int &a)//参数的顺序不同
{
    cout<<"第四个"<<endl;
    int tmp = a;
    a = b;
    b = tmp;
}

int main()
{
    int a = 1,c = 2;
    double b = 1.111;
    Swap(b,a);

    return 0;
}

3)函数重载的二义性

#include<iostream>
using namespace std;

void Add(int a,int b)
{
    cout<< a + b <<endl;
}

void Add(int a,int b,int c = 0)
{
    cout<< a + b + c<<endl;
}

int main(int argc, char const *argv[])
{
    //Add(1,2);区分不了使用哪个函数
    return 0;
}

19、c++的动态内存分配

1)new和delete的基本用法
c语言:使用malloc和free函数
c++:malloc和free仍然可以使用,但是c++提供了专门的分配方式:new和delete

2)二者区别(重要)
c语言中:malloc和free是一个函数,函数值类型是(void*),不可以初始化
c++:new和delete是一个关键词,返回值类型为申请对象的类型,可以初始化

#include<iostream>
using namespace std;

int main()
{
    int *p = new int;//分配了一个int类型的内存空间,返回值是(int *)
    *p = 100;
    cout<<"*p = "<<*p<<endl;
    delete p;

    p = NULL;


    int *q = new int(200);//分配空间并初始化
    cout<<"*q = "<<*q<<endl;
    delete q;
    q = NULL;
    
	//c++11标准,c++11之前的版本不可以初始化动态数组
    int *q2 = new int[5]{1,2,3,4,5};//分配五个int型,也就是分配个数组,里面五个int型,用()初始化
    for(int i = 0;i < 5;i++)
    {
        cout<<q2[i]<<" ";//" "是加空格
    }
    cout<<endl;

    delete []q2;//释放动态数组 需要加上[]

    q2 = NULL;

    return 0;
}

20、多维数组的创建和释放

例如:二维数组的动态创建,例如:申请二维数组int a[5][6];

#include<iostream>
using namespace std;

int main()
{
    int **a = new int*[5];//分配一个二维数组,每个数组的元素是一个指针,指向一个一维数组

    for(int i = 0;i < 5;i++)
    {
        a[i] = new int[6];//为一维数组分配空间
    }

    //使用delete来释放,只要将顺序反过来就行
    for(int i = 0;i < 5;i++)
    {
        delete []a[i];
        a[i] = NULL;
    }

    delete []a;
    a = NULL;

    return 0;
}

最后

以上就是自然信封为你收集整理的C++基础讲解第一期(超详细)一、面向对象概述二、C到C++的过度的全部内容,希望文章能够帮你解决C++基础讲解第一期(超详细)一、面向对象概述二、C到C++的过度所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部