C++入门(上)

文章目录

  • 1.命名空间
    • 1.1介绍
    • 1.2使用
  • 2.C++输入与输出
  • 3.缺省参数
    • 3.1介绍
    • 3.2使用
  • 4.函数重载
    • 4.1介绍
    • 4.2无法构成重载
    • 4.3C语言不支持重载原因
    • 4.4C//C++交叉调用
      • 4.4.1 C++调用C语言的静态库
      • 4.4.1 C调用C++语言的静态库
  • 5.引用
    • 5.1介绍
    • 5.2特性
    • 5.3使用
      • 1.做参数
      • 2.做返回值
      • 3.指针的引用
    • 5.4传参方式
    • 5.5.引用的优劣
      • 5.1传引用和传值:
      • 5.2引用和指针
      • 5.3传值、传引用效率比较
  • 6.常引用
    • 6.1介绍
    • 6.2应用

前言:为什么要学C++?
大佬们觉得C不够好,在C语言的基础上,对其进行优化和补充便有了C Plus Plus。当然,C++目前仍在不断地更新。可以这么理解,C语言是刑天,C++是战神刑天。

1.命名空间

1.1介绍

对标识符的名称进行本地化 以避免命名冲突或名字污染

关键字  名字{};
命名空间中可以定义变量/函数/类型
命名空间可以嵌套
同一个工程中允许存在多个相同名称的命名空间,最后合成同一个命名空间
namespace bit
{
int rand = 10;
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}

1.2使用

1.命名空间名 作用域限定符 成员
bit::a
2.引入某个成员
using bit::a;
3.引入命名空间
using namespace bit;

std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;

2.C++输入与输出

#include
using namespace std;
int main()
{
cout<<"Hello world!!!"<<endl;
return 0;
}
  1. cout(console out):标准输出对象(控制台)
    cin(console in):标准输入对象(键盘)
    使用二者需要:
#include
using namespace std;
  1. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,都包含在包含头文件中。
  2. <<是流插入运算符,>>是流提取运算符。
  3. C++的输入输出可以自动识别变量类型。

3.缺省参数

3.1介绍

声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实
参则采用该形参的缺省值,否则使用指定的实参。

3.2使用

1.全缺省参数
void Func(int a = 10, int b = 20, int c = 30)
{}
2.半缺省参数
void Func(int a, int b = 10, int c = 20)
{}

注意:
1.半缺省参数必须从右往左连续给值,不能间隔着给。传参从左往右依次传。
2. 缺省参数不能在函数声明和定义中同时出现,规定在声明里出现。
3. 缺省值必须是常量或者全局变量

4.函数重载

4.1介绍

C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

#include
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
	return left + right;
}
double Add(double left, double right)
{
	return left + right;
}
// 2、参数个数不同
void f()
{
	cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{
	cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
	cout << "f(char b, int a)" << endl;
}
int main()
{
	Add(10, 20);
	Add(10.1, 20.2);

	f();
	f(10);

	f(10, 'a');
	f('a', 10);

	return 0;
}

4.2无法构成重载

1.不能依靠返回值不同来构成重载,调用时无法确定调用哪个重载函数
float add(double a,double b){};
double add(double a,double b){};

add(1.1,2.2);

2.缺省值不同,不能构成重载
2.1
void test(int a){};
void test(int a = 10){};

test(1);

2.2
void test(){};
void test(int a = 0){};

test();不知道调用哪个函数
test(1);

4.3C语言不支持重载原因

要解决这个问题,需要对程序编译原理有一定了解,点击程序环境和预处理可以浅浅了解一下。当然,如想做进一步认识,可以在Linux环境下对C/C++代码调试理解。
C++入门(上)_第1张图片

4.4C//C++交叉调用

已知C程序可以调用C语言写的库,C++程序可以调用C++语言写的库,那么二者能否交叉调用呢?

答案是可以的,但是需要做一些调整和处理。

4.4.1 C++调用C语言的静态库

C库:
stack.lib
stack.h
stack.c
C++程序调用时:
1.头文件包含
#include"../stackc/stack.h"
2.链接器配置
常规--附加库目录(C库的目录)
输入--附加依赖项(C库的名称)
3.extern "C"
{
#include"../stackc/stack.h"
}
告诉C++编译器,此头文件下的函数要用C的规则去链接查找。

4.4.1 C调用C++语言的静态库

C++库:
stack.lib
stack.h
stack.cpp
C程序调用时:
1.头文件包含
#include"../stackcpp/stack.h"
2.链接器配置
常规--附加库目录(C++库的目录)
输入--附加依赖项(C++库的名称)
3.C++兼容C,想用C调用C++,只能改变C++写的库,无法通过改变C程序来实现调用。
在stack.h中,做如下操作:
#ifdef _cplusplus
extern "C"
{
#endif
函数声明;
函数声明;
函数声明;
#ifdef _cplusplus
extern "C"
}
#endif

5.引用

5.1介绍

给已存在变量取一个别名,编译器不会为引用变量开辟内存空间,二者共用同一块内存空间。

5.2特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,不能再引用其他实体

int main()
{
	int a = 10;
	int& ra = a;
	
	//err, 定义时必须初始化
	int& b;
	
	//ok, 可以有多个引用
	int& c = a;
	int& d = c;
	
	//err, 只能引用一个实体
	int x = 20;
	int& c = x;
	return 0;
}

}
int main()
{
	Test();
	return 0;
}

5.3使用

1.做参数

void Swap(int& left, int& right)
{
 int temp = left;
 left = right;
 right = temp;
}

2.做返回值

int& Count()
{
 static int n = 0;
 n++;
 return n;
}

注意:
出了函数作用域,如果返回对象还在(未还给系统),可以使用引用返回。否则必须使用传值返回。

3.指针的引用

int a = 10;
int& ra = a;
 
int* pa = &a;
int*& rpa = pa

5.4传参方式

传值、传址、传引用

#include
using namespace std;
 
void Swap(int x, int y) 
{
    int tmp = x;
    x = y;
    y = tmp;
}
 
void Swap(int* px, int* py) 
{
    int tmp = *px;
    *px = *py;
    *py = tmp;
}
 
void Swap(int& rx, int& ry) 
{
    int tmp = rx;
    rx = ry;
    ry = tmp;
}
 
int main(void)
{
    int a = 10;
    int b = 20;
 
    Swap(&a, &b);
    Swap(a, b);  //err,不知道传值还是传引用
 
    return 0;
}

5.5.引用的优劣

5.1传引用和传值:

以值作为参数或返回值类型,在传参和返回时,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者变量的一份临时拷贝,因此效率低下,当参数或者返回值类型非常大时,效率更低。

5.2引用和指针

  1. 引用定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用引用一个实体后,不能再引用其他实体,指针可以指向任何一个同类型实体
  4. 没有NULL引用,有NULL指针
  5. 在sizeof中:引用结果为引用类型的大小,指针是地址空间所占字节个数
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,而引用是编译器自己处理
  9. 引用比指针使用起来相对更安全

5.3传值、传引用效率比较

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直
接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效
率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。

  1. 作为函数参数性能比较
#include
#include 
using namespace std;
struct A
{
	int a[10000];
};
void TestFunc1(A a)
{

}
void TestFunc2(A& a)
{

}
void TestRefAndValue()
{
	A a;

	// 值作为函数参数
	size_t begin1 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc1(a);
	size_t end1 = clock();

	// 引用作为函数参数
	size_t begin2 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc2(a);
	size_t end2 = clock();

	// 两个函数运行时间
	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}

在这里插入图片描述

  1. 作为返回值类型的性能比较
#include
#include 
using namespace std;
struct A
{ 
	int a[10000]; 
};
A a;
A TestFunc1()
{
	return a;
}
A& TestFunc2() 
{ 
	return a;
}
void TestReturnByRefOrValue()
{
	// 值作为函数返回值类型
	size_t begin1 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc1();
	size_t end1 = clock();
	
	// 引用作为函数返回值类型
	size_t begin2 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc2();
	size_t end2 = clock();
	
	// 两个函数运行时间
	cout << "TestFunc1 time:" << end1 - begin1 << endl;
	cout << "TestFunc2 time:" << end2 - begin2 << endl;
}
int main()
{
	TestReturnByRefOrValue();
	return 0;
}

C++入门(上)_第2张图片

6.常引用

6.1介绍

常引用:提高程序的效率,保护传递给函数的数据不被改变

左值可修改  右值不可修改
1.a可读不可写  ra对应可读不可写
int main(void)
{
    const int a = 10;
    const int& ra = a;
    int& ra = a;  //err,权限不能被放大
    return 0;
}
2.a可读可写 ra可读不可写
int main(void)
{
    int a = 10;
    const int& ra = a;//ok,权限可以被缩小
    return 0;
}
3.const 使得接受度增加
int& b = 10; //err
const int& b = 10;//ok

double d = 3.14;
int& i = d; //err
const int& i = d;//ok
内置类型double d产生一个具有常性的临时变量(为不可更改的右值)const int赋给i

C++入门(上)_第3张图片

6.2应用

void Func(const int& x) 可读不可写
{
    cout << x << endl;
}
 int main(void)
{
    const int a = 10;可读不可写
    int b = 20;      可读可写
 
    Func(a);  
    Func(b);  
 
    return 0;
}

你可能感兴趣的:(遣返回家的C家家,c++,算法)