小白学C++请问求n!这段数控n代码表示什么问题在哪里

printf("如果你三秒钟之内什么也不输入,我就输出-1。\n");
}

c++程序在执行时,将内存大方向划分为4个区域

代码区:存放函数体的二进制代码,由操作系统进行管理的

全局区:存放全局变量和静态变量以及常量

栈区:由编译器自动分配释放,存放函数的参数值,局部变量等

堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

不同区域存放的数据,赋予不同生命周期,给我们更大的灵活编程。

程序运行前:(全局区)

在程序编译后,生成了exe可执行程序未执行该程序前分为两个区域:

  • 存放CPU执行的机器指令:二进制01010。
    • 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。
    • 代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令。
  • 全局变量静态变量存放在此。
  • 全局区还包含了常量区字符串常量其他常量也存放在此。
      • 该区域的数据在程序结束后操作系统释放

全局区存放的数据:全局变量、静态变量、常量。 

局部变量:在函数体内声明的变量。包括main函数内。

全局变量:在函数体外声明的变量。

// 全局区:存放:全局变量、静态变量、常量。 // 创建普通局部变量 // 静态变量: 在普通变量前面加上static // 常量:分为字符串常量和const修饰的变量。 // 字符串常量:双引号引起来的字符串,都可以被称为字符串常量。"Hello world."。 // const修饰变量:还可以分为:const修饰的全局常量,const修饰的局部变量(局部常量)。

自动分配和释放,存放函数的参数值,局部变量等。

注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放。

int a = 10; // 局部变量 存放在栈区,栈区的数据在函数执行完后自动释放。

由程序员分配释放,若程序员不释放,程序结束时由操作系统回收。

在C++中主要利用new关键字堆区开辟内存。

// 利用 new关键字 将数据开辟到 堆区。 // 指针本质也是局部变量,也是放在栈区,只是指针保存的实际数据在堆区。

 指针是一种类型。4个字节,保存在栈中,栈的数据内容为指向的内存地址。

new关键字可以在内存堆中开辟空间存储数据。

新建一个指向A类型的数据在堆中的地址这样一个变量。

可以由程序员释放内存空间:delete

// 在堆区创建一个整型数据。 // new 返回的是:该数据类型的指针。 // 在堆中的数据,只要程序员不主动释放,那么就一直存在。 // 堆区的数据,由程序员管理开辟,程序员管理释放。 // 如果想释放堆区的数据,利用关键字delete // 在堆区开辟一个数组: // 释放数组的时候,要加[]才可以。 //别名数据变 原也变
  • 引用在初始化后,不可以改变。
//引用初始化后,不可以改变

作用:函数传参时,可以利用引用的技术让形参修饰实参,
优点:可以简化指针修改实参

总结:引用传递和指针传递所得到的结果是相同的,引用传递是因为别名的原因。 

作用:引用时可以作为函数的返回值存在的,
注意:不要返回局部变量引用
用法:函数调用作为左值

// 第一次结果正确,因为编译器做了保留 // 第二次结果错误,因为a的内存已经释放 //引用做函数的返回值 //1、不要返回局部变量的引用 //2、函数的调用可以作为左值 test2() = 1000;//函数值调用在等号的左边存在:函数调用作为左值

本质:引用的本质在c++内部实现是一个指针常量

//本质:引用的本质在C++内部实现是一个指针常量 //指针常量是指针指向的地址不可修改 而地址上的值是可以修改的。 //C++推荐引用技术 因为语法上很简单 引用本质是指针变量 但是所有的指针操作编译器帮我们做

在c++中,函数的形参列表中的形参是可以有默认值的。

语法:返回值类型 函数名(参数=默认值){}

//1. 如果某个位置参数有默认值,那么从这个位置往后,从左向右,必须都要有默认值 //2. 如果函数声明有默认值,函数实现的时候就不能有默认参数

C++中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置

语法: 返回值类型 函数名 (数据类型){}

在现阶段函数的占位参数存在意义不大,但是后面的课程中会用到该技术

//函数占位参数 ,占位参数也可以有默认参数

作用: 函数名可以相同,提高复用性

注意: 函数的返回值不可以作为函数重载的条件

//函数重载需要函数都在同一个作用域下 //函数返回值不可以作为函数重载条件
  • 函数重载碰到函数默认参数
  • //1、引用作为重载条件 //2、函数重载碰到函数默认参数

C++面向对象的三大特性为:封装、继承、多态。

C++认为万事万物都皆为对象,对象上有其属性和行为

        人可以作为对象,属性有姓名、年龄、身高、体重...行为有走、跑、跳、吃饭、唱歌...

        具有相同性质的对象,我们可以抽象称为类,人属于人类,车属于车类

封装是C++面向对象三大特性之一

  • 将属性和行为作为一个整体,表现生活中的事物
  • 将属性和行为加以权限控制

1.将属性和行为作为一个整体,表现生活中的事物

语法:class 类名{ 访问权限: 属性 / 行为 };

示例1:设计一个圆类,求圆的周长

//设计一个圆类,求圆的周长 //圆求周长公式:2*PI*半径 //class代表设计一个类,类后面紧跟着的就是类的名称 //通过圆类 创建具体的圆(对象) //实例化(通过一个类 创建一个对象的过程) //给圆对象 的属性进行赋值

 设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,可以显示学生好的姓名和学号

//类中的属性和行为 我们统一称为 成员 //属性 成员属性 成员变量 //行为 成员函数 成员方法

类在设计时,可以把属性和行为放在不同的权限下,加以控制

//公共权限 public 成员 在类内可以访问 类外可以访问 //保护权限 protected 成员 在类内可以访问 类外不可以访问 (儿子也可以访问父亲保护内容) //私有权限 private 成员 在类内可以访问 类外不可以访问 (儿子不可以访问父亲的私有内容)
  • class 默认权限为私有

优点1: 将所有成员属性设置为私有,可以自己控制读写权限

优点2:对于写权限,我们可以检测数据的有效性

设计立方体类(Cube)

求出立方体的面积和体积

分别用全局函数和成员函数判断两个立方体是否相等

//3.设计行为 获取立方体的面积和体积 //4.分别利用全局函数和成员函数 判断两个立方体是否相等 //利用成员函数判断两个立方体是否相等 //利用全局函数判断 两个立方体是否相等 //创建一个立方体对象 //利用全局函数判断的

设计一个圆形类(Circle),和一个点类(Point),计算点和圆的关系

//在类中可以让另一个类 作为本类的一个成员 //计算两点距离的平方

 对象的初始化和清理

  • 生活中我们买的电子产品都基本会有出厂设置,在某一天我们不用的时候也会删除一些自己信息数据保证安全
  • C++中的面向对象来源于生活,每个对象也都会有初始设置以及对象销毁前的清理数据的设置

构造函数和析构函数 

对象和初始化和清理也是两个非常重要的安全问题 

一个对象或者变量没有初始状态,对其使用后果是未知

同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题

C++利用了构造函数和析构函数解决上述问题,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。

对象的初始化和清理工作是编译器前置我们做的事情,因此如果我们不提供构造和析构,编译器会提供

编译器提供的构造函数和析构函数是空实现

构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动调用
析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作

构造函数语法:类名(){}

  1. 构造函数,没有返回值也不写void
  2. 构造函数可以有参数,因此可以发生重载
  3. 程序在调用对象时候会自动调用构造,无需手动调用,而且只会调用一次
//对象的初始化和清理 //1.构造函数 进行初始化操作 //2.析构函数 进行清理的操作 person p;//在栈上的数据,test01执行完毕后,释放这个对象

 构造函数的分类及调用

//1.构造函数的分类和调用 // 按照参数分类 无参构造(默认构造)和有参构造 // 按照类型分类 普通构造和拷贝构造 //将传入的人身上的所有属性,拷贝到我身上 Person20 p; //默认构造函数调用,p后面不加(),编译器会把Person p()看成一个函数的声明 //Person(10);匿名对象,特点:当前执行结束后,系统会立即回收掉匿名对象

 拷贝构造函数调用时机

C++中拷贝构造函数调用时机通常有三种情况

使用一个已经创建完毕的对象来初始化一个新对象

值传递的方式给函数参数传值

// 1.使用一个已经创建完毕的对象来初始化一个新对象 // 2.值传递的方式给函数参数传值 // 3.以值方式返回局部对象

默认情况下,c++编译器至少给一个类添加3个函数

1.默认构造函数(无参,函数体为空)

2.默认析构函数(无参,函数体为空)

3.默认拷贝构造函数,对属性进行值拷贝

构造函数调用规则如下:

如果用户定义有参构造函数,c++不在提供无参构造,但是会提供默认拷贝构造

如果用户定义拷贝构造函数,c++不会再提供其他构造函数

//如果写了有参构造函数,编译器就不会再提供无参构造函数,但依然会提供拷贝构造函数 //如果写了拷贝构造函数,编译器既不会提供无参构造函数也不会提供有参构造函数

浅拷贝:简单的赋值拷贝操作。

深拷贝:在堆区中重新申请空间,进行拷贝操作。

//自己实现拷贝构造函数 解决浅拷贝带来的问题 //析构代码,将堆区开辟数据做释放操作

作用:C++提供了初始化列表语法,用来初始化属性

语法:构造函数( ):属性1(值1),属性2(值2)… { }

//初始化列表:初始化属性

 类对象作为类成员

C++类中的成员可以是另一个类的对象,我们称该成员为对象成员

静态成员就是在成员函数前加上关键字static,称为静态成员

1、所有对象共享同一份数据;

3、类内声明,类外初始化。

 静态成员函数:

1、所有对象共享同一个函数;

2、静态成员函数只能访问静态成员变量。

报错,无法解析p.m_A,因为类外无法访问,要先在类外初始化才行,而且必须是在全局范围初始化。

在全局范围类外初始化要这样写:数据类型  类名::属性=初始化值

所有对象共享同一份数据

p和p2共享同一个m_A,所以都是100

扩展一个知识,可以用对象进行访问或者用类名进行访问

这里主函数里用两种方法访问m_A的值,都是正确的。因为这个m_A是所有对象公用的,所以可以通过类名访问,不需要写出是哪个对象的m_A

静态成员变量也是有访问权限的

把m_A的访问权限改为private,在主函数里就无法访问m_A了

1、在类中m_B无法赋值,因为静态成员函数只能访问静态成员变量;

2、主函数里访问func2()函数报错,因为func2()函数时private的访问权限,类外无法访问。

成员变量和成员函数分类储存

只有非变量存储在类的对象中

1.空对象有一个字节,用来区分对象

每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码

那么问题是:这块代码是如何区分那个对象调用自己的呢?

c++通过提供特殊的对象指针,this指针,解决上述问题。this指针指向被调用的成员函数所属的对象

this指针是隐含每一个非静态成员函数内的一种指针

this指针不需要定义,直接使用即可

当形参和成员变量同名时,可用this指针来区分

在类的非静态成员函数中返回对象本身,可使用return *this

//1、当形参和成员变量同名时,可用this指针来区分,解决名称冲突


C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针

如果用到this指针,需要加以判断保证代码的健壮性

//空指针访问成员函数 p->ShowPerson(); //不能访问成员变量,成员函数中用this指针判断空指针,就可以了。

生活中你的家有客厅(Public),有你的卧室(Private)

客厅所有来的客人都可以进去,但是你的卧室是私有的,
在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术
友元的目的就是让一个函数或者类 访问另一个类中私有成员


运算符重载概念:对已有的运算符重新定义,赋予另一种功能,以适应不同的数据类型

作用:实现两个自定义数据类型相加的运算。

//成员函数实现 + 号运算符重载 //全局函数实现 + 号运算符重载 //运算符重载 可以发生函数重载
}

我要回帖

更多关于 c语言code用法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信