C++_基础_C与C++的区别2

内容:
(1)C++中的函数
(2)动态内存
(3)引用
(4)类型转换
(5)C++社区对C程序员的建议

1.C++中的函数
1.1 函数的重载
(1)重载的概念
在同一个作用域中,函数名相同,函数的参数列表不同构成重载关系,在不同的作用域中遵循标示符隐藏原则

(2)函数重载的方式
a.函数名相同,参数类型不同
b.函数名相同,参数个数不同
c.函数名相同,参数顺序不同
d.函数名相同,const修饰的常函数和普通成员函数构成重载(以后讲到)

(3)比较特殊的重载方式
(4)重载匹配的原则
完全匹配 > 常量转换 > 升级转换
> 标准转换 > 自定义类型转换(以后讲到) > 省略匹配

1.2 函数重载的原理
(1)C++编译器通过对函数进行换名,将参数表信息体现在新的函数名中,从而实现重载
如:
void show(int i,int j){}
=> _Z4showii; 换名之后的新名字
void show(int j,int i)
=> _Z4showii;

(2)C程序也可以通过C++编译器换名后的新函数名调用C++模块中的函数
(3)通过extern "C" 关键字可以明确要求C++编译器不要对函数进行换名的操作,以满足C程序可以直接调用C++模块中的函数

1.3 缺省参数
函数的参数有缺省值,也就是默认值
如:
void foo(int i,char c = ‘A‘,char* p = NULL) {...}

foo(66,‘B‘,"hello");
foo(66,‘B‘); // p = NULL;
foo(66); // c = ‘A‘,p = NULL

注意:
(1)缺省参数必须靠右。如果某一个参数带有缺省值,那么该参数右边的所有参数都必须有缺省值
如:
void foo(int i,char c = ‘A‘,char* p){} // error
foo(66,"hello");

(2)如果函数的声明和定义分开,那么缺省参数的值只能写在函数的声明部分
如:
void foo(int i,char c = ‘A‘,char* p = NULL);

void foo(int i,char c,char* p){}

(3)注意防止由于缺省参数而引发的重载冲突问题

扩展:
(1)void fn(){}; 在C语言中表示可以接受任意多个任意类型的实参;在C++中表示不接受任何实参
(2)在C语言中可以不对函数进行声明,会自动做隐式声明;在C++中调用函数之前必须对所调用的函数进行声明,或者将被调用函数的定义放在调用函数之前

1.4 哑元
只有数据类型没有名称的参数叫哑元
如:
void fn(int){}
fn(); //error
fn(66); // ok

用途:
(1)为了兼容以前的代码
(2)用于运算符重载,主要用于区分前后缀自增减运算符(以后讲到)

1.5 内联
使用inline关键字修饰的函数叫做内联函数
类似于C语言中的宏函数,可以进行指令的替换,相对于宏函数有一定的优势,可以检查数据类型,可以计算表达式的值等等

注意:
inline关键字修饰函数,仅仅表示这是一种建议而不是要求,所有使用inline关键字修饰的函数不一定会做内联的处理;反之,没有使用inline关键字修饰的函数也可能根据编译器的优化策略进行内联处理

练习:
自定义一个计算int类型参数平方的函数,并且通过返回值返回计算的结果,分别使用inline修饰和不修饰去观察是否内联

扩展:
(1)多次调用的小而简单的函数适合内联
(2)调用次数极少并且大而复杂的函数不适合内联
(3)递归函数无法内联

2.动态内存
C语言中: malloc/calloc/realloc/free 函数

C++中:
除了提供对C的兼容之外,还提供了 new/delete运算符来管理动态内存

2.1 申请指定数据类型变量大小的内存
int* pi = new int;
delete pi; pi = NULL;

int* pi = new int(66);
delete pi; pi = NULL;

2.2 申请指定的数组大小的内存
int* pi = new int[10];
delete[] pi; pi = NULL;

//C++11/C++0x标准支持
int* pi = new int[10]{...};
delete[] pi; pi = NULL;

提问:
int* pi = new int; //ok
int* pi = new int[5]; //ok
int* pi = new int[3][4];//error
int** pi = new int[3][4]; error

2.3 使用new操作符分配N维数组时,返回N-1维的数组指针
如:
int (*pi)[4] = new int[3][4];
delete[] pi; pi = NULL;

int (*pi)[3][4]
= new int[2][3][4];
delete[] pi; pi = NULL;

在[]后面使用{}进行初始化,需要C++11/C++0x标准的支持

2.4 定位分配
new(指针) 数据类型(初始值);
|
这里的指针表示分配内存的起 始位置

功能:
主要用于在一个已经分配好的内存空间再次分配内存

3.引用

3.1 概念
引用并不是一种独立的数据类型,类似于C中的指针,其实是变量的别名

如:
int a = 10;
int& b = a;
=> 给a起了个别名叫b,b = 10;
int& c = b;
=> int& c = a; c = 10;

3.2 引用和指针的区别
(1)引用必须初始化,指针可以不初始化
int& a; // error
int* pa; // 野指针

(2)引用不可以为空,指针可以为空
int& a = NULL; //error
const int& a = NULL; //常引用
const int& a = 11; // ok
int* pi = NULL; //空指针

(3)引用不可以更换目标,指针可以
int a = 10;
int& b = a;
int m = 20;
b = m; => a = m; 赋值

int* pi = &a;
pi = &b;

(4)不能声明引用型数组,可以声明指针型数组
int& arr[10]; //error
int* arr[10]; //ok
int arr[10]; //ok
int (*arr)[10]; //ok

建议:
在C++程序尽量去使用引用,而少使用指针,因为指针容易出现野指针,容易出现段错误

作业:
查询signal函数,并且将signal函数的原型组合出来

明日预报:
(1)引用
(2)类型转换
(3)C++社区给C程序员的建议
(4)面向对象编程的概念
(5)类和对象
(6)构造函数
(7)初始化列表及其必要性

复习:
1.C++的简介和编程变化
1.1 C语言的简介
贝尔实验室 汤普逊 B语言,在B语言的基础上修改和扩展,New B语言,后来改名为 C语言,出生于1972年

1.2 C++简介
在C语言的基础上,BS扩展C语言,New C语言,改名为 C With Classes(带类的C),++运算符,C++

1.3 历史事件
1998年 出现C++的标准 C++98
2003年 C++98修订 C++03
2011年 C++11标准(C++0x)

1.4 C++和C语言的比较
(1)都是编译型语言
(2)属于强类型语言
(3)C++兼容C,提供了更多的特性
a.语言风格更加简洁
b.类型检查更加严格(void* int*)
c.支持面向对象编程
d.支持异常处理
e.支持运算符重载
f.支持泛型编程

1.5 用途
(1)用于游戏开发
(2)系统开发和驱动开发

1.6 编程变化
(1)文件的扩展名
源文件:.cc/.C/.cxx/.cpp
头文件:.hpp .h
(2)头文件
#include <iostream>
#include <cstdio>
(3)输入输出
cout << / cin >>
(4)编译器变化
g++/c++ xxx.cpp
gcc/cc xxx.cpp -lstdc++
(5)命名空间
using namespace std;

2.命名空间
2.1 自定义命名空间
namespace 命名空间名
{
变量、函数等等
}

2.2 使用命名空间的方式
(1)使用名字空间指令的方式
using namespace std;
(2)使用作用域限定符
std::cout << "大家好才是真的好" << std::endl;
(3)使用名字空间声明的方式
using std::cout;
using std::endl;
cout << "大家好才是真的好" << endl;

2.3 无名命名空间
如果一个标示符没有被放置于任何命名空间中,默认放在无名/匿名名字空间中,使用方式:
::标示符

2.4 扩展
(1)命名空间中的内容可以分开去写
(2)命名空间中的函数声明和定义分开
(3)命名空间可以嵌套

3.结构体、联合、枚举不同
3.1 结构体的不同
(1)定义结构体变量时可以省略struct关键字
(2)结构体中可以定义函数

3.2 联合的不同
(1)定义联合变量时可以省略union关键字
(2)支持匿名联合

3.3 枚举的不同
(1)定义枚举类型变量时可以省略enum关键字
(2)枚举是一种独立的数据类型,不能使用整型进行赋值

4.bool类型和运算符别名
4.1 bool类型
bool 是C++中的基本数据类型,数值有两种:true 和 false, 也就是1和0,
本质上是单字节的整数,对于任意的基本数据类型都可以隐式的转换为bool类型,使用boolalpha指定输出的格式为:true 和 false

bool类型可以定义变量,作为函数的返回值和参数,也可以定义指针

4.2 别名
&& and & bitand
|| or | bitor ...
----------------------------------
今天内容:
(1)C++中的函数
(2)动态内存
(3)引用
(4)类型转换
(5)C++社区对C程序员的建议

1.C++中的函数
1.1 函数的重载
(1)重载的概念
在同一个作用域中,函数名相同,函数的参数列表不同构成重载关系,在不同的作用域中遵循标示符隐藏原则

(2)函数重载的方式
a.函数名相同,参数类型不同
b.函数名相同,参数个数不同
c.函数名相同,参数顺序不同
d.函数名相同,const修饰的常函数和普通成员函数构成重载(以后讲到)

(3)比较特殊的重载方式
(4)重载匹配的原则
完全匹配 > 常量转换 > 升级转换
> 标准转换 > 自定义类型转换(以后讲到) > 省略匹配

1.2 函数重载的原理
(1)C++编译器通过对函数进行换名,将参数表信息体现在新的函数名中,从而实现重载
如:
void show(int i,int j){}
=> _Z4showii; 换名之后的新名字
void show(int j,int i)
=> _Z4showii;

(2)C程序也可以通过C++编译器换名后的新函数名调用C++模块中的函数
(3)通过extern "C" 关键字可以明确要求C++编译器不要对函数进行换名的操作,以满足C程序可以直接调用C++模块中的函数

1.3 缺省参数
函数的参数有缺省值,也就是默认值
如:
void foo(int i,char c = ‘A‘,char* p = NULL) {...}

foo(66,‘B‘,"hello");
foo(66,‘B‘); // p = NULL;
foo(66); // c = ‘A‘,p = NULL

注意:
(1)缺省参数必须靠右。如果某一个参数带有缺省值,那么该参数右边的所有参数都必须有缺省值
如:
void foo(int i,char c = ‘A‘,char* p){} // error
foo(66,"hello");

(2)如果函数的声明和定义分开,那么缺省参数的值只能写在函数的声明部分
如:
void foo(int i,char c = ‘A‘,char* p = NULL);

void foo(int i,char c,char* p){}

(3)注意防止由于缺省参数而引发的重载冲突问题

扩展:
(1)void fn(){}; 在C语言中表示可以接受任意多个任意类型的实参;在C++中表示不接受任何实参
(2)在C语言中可以不对函数进行声明,会自动做隐式声明;在C++中调用函数之前必须对所调用的函数进行声明,或者将被调用函数的定义放在调用函数之前

1.4 哑元
只有数据类型没有名称的参数叫哑元
如:
void fn(int){}
fn(); //error
fn(66); // ok

用途:
(1)为了兼容以前的代码
(2)用于运算符重载,主要用于区分前后缀自增减运算符(以后讲到)

1.5 内联
使用inline关键字修饰的函数叫做内联函数
类似于C语言中的宏函数,可以进行指令的替换,相对于宏函数有一定的优势,可以检查数据类型,可以计算表达式的值等等

注意:
inline关键字修饰函数,仅仅表示这是一种建议而不是要求,所有使用inline关键字修饰的函数不一定会做内联的处理;反之,没有使用inline关键字修饰的函数也可能根据编译器的优化策略进行内联处理

练习:
自定义一个计算int类型参数平方的函数,并且通过返回值返回计算的结果,分别使用inline修饰和不修饰去观察是否内联

扩展:
(1)多次调用的小而简单的函数适合内联
(2)调用次数极少并且大而复杂的函数不适合内联
(3)递归函数无法内联

2.动态内存
C语言中: malloc/calloc/realloc/free 函数

C++中:
除了提供对C的兼容之外,还提供了 new/delete运算符来管理动态内存

2.1 申请指定数据类型变量大小的内存
int* pi = new int;
delete pi; pi = NULL;

int* pi = new int(66);
delete pi; pi = NULL;

2.2 申请指定的数组大小的内存
int* pi = new int[10];
delete[] pi; pi = NULL;

//C++11/C++0x标准支持
int* pi = new int[10]{...};
delete[] pi; pi = NULL;

提问:
int* pi = new int; //ok
int* pi = new int[5]; //ok
int* pi = new int[3][4];//error
int** pi = new int[3][4]; error

2.3 使用new操作符分配N维数组时,返回N-1维的数组指针
如:
int (*pi)[4] = new int[3][4];
delete[] pi; pi = NULL;

int (*pi)[3][4]
= new int[2][3][4];
delete[] pi; pi = NULL;

在[]后面使用{}进行初始化,需要C++11/C++0x标准的支持

2.4 定位分配
new(指针) 数据类型(初始值);
|
这里的指针表示分配内存的起 始位置

功能:
主要用于在一个已经分配好的内存空间再次分配内存

3.引用

3.1 概念
引用并不是一种独立的数据类型,类似于C中的指针,其实是变量的别名

如:
int a = 10;
int& b = a;
=> 给a起了个别名叫b,b = 10;
int& c = b;
=> int& c = a; c = 10;

3.2 引用和指针的区别
(1)引用必须初始化,指针可以不初始化
int& a; // error
int* pa; // 野指针

(2)引用不可以为空,指针可以为空
int& a = NULL; //error
const int& a = NULL; //常引用
const int& a = 11; // ok
int* pi = NULL; //空指针

(3)引用不可以更换目标,指针可以
int a = 10;
int& b = a;
int m = 20;
b = m; => a = m; 赋值

int* pi = &a;
pi = &b;

(4)不能声明引用型数组,可以声明指针型数组
int& arr[10]; //error
int* arr[10]; //ok
int arr[10]; //ok
int (*arr)[10]; //ok

建议:
在C++程序尽量去使用引用,而少使用指针,因为指针容易出现野指针,容易出现段错误

作业:
查询signal函数,并且将signal函数的原型组合出来

时间: 2024-10-10 04:44:03

C++_基础_C与C++的区别2的相关文章

python中_、__和__xx__的区别

python中_.__和__xx__的区别 本文为译文,版权属于原作者,在此翻译为中文分享给大家. 英文原文地址:Difference between _, __ and __xx__ in Python 在学习Python时,很多人都弄不清楚各种下划线的意思,而且在这之前已经给其他人解释过很多遍了,是时候把它记录下来. "_"单下划线 Python中不存在真正的私有方法.为了实现类似于c++中私有方法,可以在类的方法或属性前加一个“_”单下划线,意味着该方法或属性不应该去调用,它并不

Hive基础之各种排序的区别

order by 1.order by会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局排序): 只有一个reducer会导致当输入规模较大时,需要较长的计算时间,速度很非常慢: 2.hive.mapred.mode(默认值是nonstrict)对order by的影响 1)当hive.mapred.mode=nonstrict时,order by和关系型数据库中的order by功能一致,按照指定的某一列或多列排序输出: 2)当hive.mapred.mode=st

Swift教程_基础技术_获取当前日期时间、日期时间格式化及转换

Swift教程_基础技术_类型转换(父子类转换:Int.Double.String转换) Swift教程_基础技术_获取当前日期时间.日期时间格式化及转换 1.获取当前日期时间 var nowDate = NSDate() var formatter = NSDateFormatter() formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" var dateString = formatter.stringFromDate(nowDate) pri

Ibatis基础知识:#与$的区别

背景 Ibatis是一个轻量级.非侵入式的持久层框架,适用于范围较广.较轻便--当然,无论J2EE中哪一个持久层框架,都会基于JDBC(不细究JNDI方式).我们在SqlMap中编写SQL,利用各种SqlMap标签处理业务逻辑,利用参数标记传递参数. 在实际开发过程中,弄明白#号和$号的区别很重要,下面我们就来分析一下这两个SqlMap参数标记. 参数标记 #号方式 解析以#号标记的参数时,Ibatis直接利用JDBC提供的参数标记(?号),将内存中的参数传递给数据库.这时,我们须要保证Java

第一天的代码练习_基础

//第一天的内容包括JAVA环境配置,数据类型的讲解,数据类型的运算.在环境配置中,要求在 cmd命令窗口下,在任何文件目录下,输入javac.exe,都能够出现正确的显示结果--就需要在环境变量 中设置 public class Test{      public static void main(String[] args){        //不能使用保留字.关键字       /*       变量定义的格式 :数据类型 变量名=初始化值       变量必须先赋值,后使用       

微信小程序_基础组件大全

微信小程序_基础组件 微信小程序为小程序开发者提供了一系列小程序基础组件,开发者可以通过组合这些小程序基础组件进行微信小程序的快速开发. 微信小程序组件是什么?微信小程序组件怎么用? 小程序组件是视图层的基本组成单元.小程序组件自带一些功能与微信风格的样式.一个小程序组件通常包括开始标签和结束标签,属性用来修饰这个组件,内容在两个标签之内. <tagname property="value"> Content goes here ... </tagename>

Java千百问_03基础语法(020)_注解、注释有什么区别

java注释注解×注释注解区别×注释注解混淆×java注释注解区别×注解与注释不同点× 点击进入_更多_Java千百问 1.注解.注释有什么区别 了解注释看这里:注释是什么 了解注解看这里:注解是什么 注解和注释很多人会混淆,它们之间的应用场景和具体使用完全不同,具体如下: 用途不同 注解通过标注包.类.字段.方法.局部变量.方法参数等元素,告诉JVM这些元素的附加信息(元信息). 注释是用来告诉开发人员这段代码的逻辑.说明.特点等,可以无限制的自由发挥. 具体使用不同 注解通过@来标注响应的元

2.java学习_基础知识(标识符、常量、变量、运算符)

标识符 定义 在程序中我们自定义的一些名称在编程的过程中,经常需要在程序中定义一些符号来标记一些名称,如包名.类名.方法名.参数名.变量名,这些符号被称为标识符. 组成元素 英文大小写字母 数字0~9 下划线_和美元符号$ 规则 不可以以数字打头,如:4student ,×不可以使用java的关键字,如class不能使用严格区分大小写,如Xxx和xxx,是两个变量 原则 见名知意,驼峰命名 规范 掌握包名多个单词组成时,所有单词都小写.举例:xxxyyyzzz类名和接口名多个单词组成时,所有单词

Java千百问_01基本概念(014)_同步、异步有什么区别

点击进入_更多_Java千百问 1.同步.异步有什么区别 在进行网络编程时,我们通常会看到同步.异步.阻塞.非阻塞四种调用方式以及他们的组合. 了解阻塞.非阻塞看这里:[阻塞.非阻塞有什么区别][2] [2]: 其中同步方式.异步方式主要是由客户端(client)控制的,具体如下: 同步(Sync) 所谓同步,就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作. 根据这个定义,Java中所有方法都是同步调用,应为必须要等到结果后才会继续执行.我们在说同步.异步的时候,一