【C++】程序设计进阶——C++

一、C++与C语言的区别

1.1 输入输出

  • C语言输入输出数据,需要记忆对应格式字符
#include<stdio.h>
int main() {
	int a;
	scanf_s("%d", &a);
	printf("%d", a);
	return 0;
}
  • C++自动根据输入输出的数据类型进行处理,不需要程序员记忆格式制符
#include<iostream>
using namespace std;

int main() {
	int a;
	cin >> a;
	cout << a << endl;
	return 0;
}

C++的标准库<iostream>定义了4个IO对象:

  •  cin:istream对象,标准输入。
  • cout:ostream对象,标准输出。
  • cerr:标准错误。用来输出警告和错误信息给程序的使用者。
  • clog:用来产生程序执行的一般信息。

"<<"操作符

  • "<<"是预定义的插入符,作用在cout上可实现屏幕输出。 

">>"操作符

  • ">>"是预定义的提取符,作用在cin上可实现键盘输入。

1.2 数据类型与表达式

 C++相对C语言的新增数据类型:布尔型bool,引用类型type&,类类型class

  • 布尔型bool:false or true
  • 引用类型type&:同一个变量空间,取个别名。
int value;
int &p=value;
  • 类类型class:协助程序员实现面向对象思想。
#include <iostream>
using namespace std;

//定义一个类
class Point {
private:
  int x;
  int y;

public:
  // 构造函数
  Point(int a, int b) {    x = a;    y = b;  }

  // 成员函数
  void display() {
    cout << "x = " << x << ", y = " << y << endl;
  }
};

int main() {
  // 创建一个Point对象,并传入参数
  Point p(3, 4);
  
  // 调用对象的成员函数
  p.display();

  return 0;
}

C++与C语言的类型转换规则相同:从内存小的向大的转换,低类型向高类型转换,一般没问题;高类型向低类型转换,可能会造成数据丢失。(低类型->高类型)

\left.\begin{matrix} bool\\ char\\ short \end{matrix}\right\}\rightarrow int\rightarrow unsigned\rightarrow long\rightarrow unsigned long\rightarrow double

1.3 动态内存管理

动态内存管理用处非常大,但在计算要分配的空间大小时非常不方便。

C++提供了新的动态内存管理方式

  • C语言:使用malloc进行动态内存分配,使用free进行动态内存释放。必须程序员手工计算具体要分配多大的字节空间数。
  • C++:使用new和delete实现动态内存的分配和回收。不需要程序员计算分配空间大小,程序可以直接通过类型名自动计算并分配合适空间的大小。

1.3.1 动态分配和释放单个数据的存储区

#include<iostream>
using namespace std;

int main() {
	int* p;
	p = new int;
	if (p = NULL) {
		cout << "Allocation failure\n";
	}
	else {
		*p = 15;
		cout << *p;
		delete p;
	}
	return 0;
}
  • 在动态分配内存的同时存入数据
int *p;
p=new int(100);
delete p;

  • 如果p=new int(98.5),会怎么样?会出现类型转换,数据从double转为int。
  • delete释放的内存空间必须是由new分配的,否则执行delete时将会导致严重的错误。(new没分配内存给p,p就是未知空间,删除未知空间很危险)

1.3.2 动态分配和释放一维数组的存储区

#include<iostream>
using namespace std;

int main() {
	int* p;
	p = new int[100];
	if (p == NULL) {
		cout << "Allocation failure!\n";
	}
	else {
		for (int i = 0; i < 100; i++)
			p[i] = i + 1;
		for (int j = 0; j < 100; j++)
			cout << p[j] << ' ';
		delete[]p;
	}
	return 0;
}

1.3.3 动态分配和释放二维数组的存储区 

1.4 函数重载

C++中的函数重载是指在同一个作用域中定义多个同名函数,但它们的参数列表不同(包括参数个数、参数类型、参数顺序等),以便根据不同的参数类型或参数个数来选择调用合适的函数。

函数重载的语法规则如下:

  1. 函数名相同
  2. 参数列表不同(包括参数个数、参数类型、参数顺序等)
  3. 返回值类型可以相同也可以不同

注:

  1. 不能以形参名字不同or函数返回类型的不同来区分函数。
  2. 不要将不同功能的函数定义为重载函数,以免出现混淆。

 函数重载中的默认形参

  • 用一个函数能够表示重载的两个函数。
int add(int x){return (x);}
int add(int x,int y){return (x+y);}
int add(int x,int y=0){return(x+y);}
  • 带默认形参值的函数

在定义函数时预先声明默认的形参值,调用时如果给出实参,则用实参初始化形参;否则采用预先声明的默认形参值。

int add(int x=6,int y=5){return x+y;}
int main(){
    int a,b,c;
    a=add(10,20);//a=30
    b=add(10);   //b=15
    c=add();     //c=11
    return 0;
}
  • 默认形参必须按照从右到左的顺序声明。在有默认值的形参右边,不能出现无默认值的形参。(不按照这种规则,在实际参数传递过程中就会出现问题)

int add(int x,int y=0){return(x+y);}    (√)

int add(int x=0,int y){return(x+y);}    (×)

  • 在相同的作用域内,默认形参值的说明应保持唯一;但在不同的作用域内,允许说明不同的默认形参值。

1.5 内联函数

C++相比C语言,还多了一个内联函数

  • 出现原因:在C++中既要运算速度快,又要有类型检查。

宏定义没有类似于普通函数调用时的系统开销,并且宏定义的参数可以适宜大多数类型的数据,达到函数重载类似的效果。但宏定义有时会产生不可预料的副作用,因为宏定义是直接替换,并不是对参数进行处理之后再计算。而且宏定义没有类型检查。

  • 用inline定义内联函数

C++中的内联函数既具有宏定义的优点,又克服了宏定义的缺点。

使用方式:在函数名前加上“inline”,即内联函数。

inline void func(int a,int b);//在编译时调用func的地方用函数体进行了替换,所以程序执行时                                              会减少调用开销。

  • 内联函数是用来提升运行效率的,只有那些频繁被调用且函数体较小的函数定义为内联函数。内联函数内不允许有循环语句和switch语句,否则按照普通函数来处理。

1.6 常量

  • 使用数字常量(指在程序运行过程中,其值不能被改变的量)有两个问题:可读性差,可修改性差。
  • 程序员通常用符号常量来解决数字常量的问题,有两种使用符号常量的方式:
  1. 宏定义:#define 符号常量名 数值
  2. C99的const常量:const 数据类型 符号常量名=数值;

注:在声明时一定要赋初值,而且在程序中间不能改变其值。

用"#define"和用"const"定义符号常量的本质区别:

  •  用"#define"定义的符号变量只在编译时完成宏替换(简单的字符串替换),在程序运行过程中不占内存空间。
  • 用"const"定义的符号常量在程序运行期间占据内存空间,只是用const来指明该内存空间的只读约束。

1.7 引用

引用type&:引用就是给一个单元起一个别名,引用与它所引用的变量共享存储单元。

引用的三种用法:

  • 独立引用

在声明独立引用时,必须对它进行初始化,这种情况下的别名绑定是永久的。

初始化独立引用的几种方式:

  1. "="右端是一个变量
    int a;
    int &ra=a;
  2. "="右端是一个常量
    const float &ra=1.0;
  3. 定义常引用
    int x=1;
    const int &rx=x;

  • 作为函数参数

C/C++采用“传值”的方式进行传递参数,在这种情况下,实参和形参是两个不同的单元,在结合时,实参的值将会被拷贝到形参中。形参的改变不会影响到实参。

  1. C语言中,采用传递指针的方式,解决了形参和实参之间数据传递的问题。
    int* swap(int* a, int* b);
    
    int main() {
        int a = 2, b = 3;
        swap(&a, &b);
        cout << a << ' ' << b;
        return 0;
    }
    
    int* swap(int* a, int* b) {
        int t = *a;
        *a = *b;
        *b = t;
        return 0;
    }
  2. C++中,采用传递引用的方式。在这种情况下,形参的名字将被看作是实参的别名,即形参就是实参本身。此时,对形参的改变也就直接改变了实参。
    void swap(int& a, int& b) {
        int t = a;
        a = b;
        b = t;
    }
    
    int main() {
        int a = 2, b = 3;
        swap(a, b);
        cout << a << ' ' << b;
        return 0;
    }
  • 作为参数返回类型

函数返回引用,实际上返回的是一个存储单元(变量),即“左值”。

如果一个函数返回引用,那么函数调用可以出现在复制号的左边。

int& f(int* pint) {
	return *pint;
}
int main() {
	int a = 10, b;
	b = f(&a) * 5;
	f(&a) = 88;
	cout << b << ' ' << a;//b=50,a=88
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

琛:D

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值