IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> #C++第一章#:C++初探 -> 正文阅读

[C++知识库]#C++第一章#:C++初探

1、写一个Hello World

在这里插入图片描述
在上图这个程序中,我们需要一个能具备输出Hello World功能的函数.
C++中的函数是啥?

函数

函数是一段能被反复调用的代码,可以接收输入,进行处理并(或)产生输出。它主要由返回类型、函数名、形参列表、函数体组成。

返回类型

表示了函数返回结果的类型,可以为void。如上图中int main()中的int。

函数名

用于函数调用。如上图中int main()中的main。

形参列表

表示函数接收的参数类型(可以为空,可以为void,可以无形参)。int main()中()里面表示main函数所包含的所有形参列表(函数里可以有形式参数,我们调用该函数时,是用实际的参数传进该函数,替换掉形参)

以下代码是有一个形参的情况。

#include <iostream>
//定义fun函数
void fun(const char* pInfo)//const char* pInfo是一个形参
{
 std::cout << pInfo << std::endl;//大括号里面是函数体
 return;//这么写也可以。表示从fun函数中退出,但没返回值。但return 0;就不行
}
int main()  //mian函数比较特殊。他是程序的入口,main函数体里面可以通过“函数名”(如fun)来搜索想要调用的函数
{
 fun("Hello World");//在mian函数里面调用fun函数,把实参"Hello World"赋给形参pInfo
 fun("Hello xzx");//一个函数是可以被反复调用的
}

以下代码是形参列表里面有多个形参的情况。在main函数里面调用fun函数,把实参"Hello World"赋给形参pInfo,把实参0赋给形参pValue(和JAVA中的方法很像)。

#include <iostream>
//定义fun函数
void fun(const char* pInfo, int pValue )  //const char* pInfo是一个形参,const char*指定了pInfo类型。int pValue 是另一个参数,参数之间用逗号划分
{
 std::cout << pInfo << std::endl;  //大括号里面是函数体
}
int main()  //mian函数比较特殊。他是程序的入口,main函数体里面可以通过“函数名”(如fun)来搜索想要调用的函数
{
 fun("Hello World",0);  //在main函数里面调用fun函数,把实参"Hello World"赋给形参pInfo,把0赋给pValue
 fun("Hello xzx",9);  //一个函数是可以被反复调用的
}

在这里插入图片描述

形参列表可以为空

#include <iostream>
//定义fun函数
void fun()
{
 std::cout << "xzx" << std::endl;//大括号里面是函数体
}
int main()//mian函数比较特殊。他是程序的入口,main函数里面可以通过“函数名”来搜索想要调用的函数{
 fun();//在mian函数里面调用fun函数
}

在这里插入图片描述
形参列表也可以写viod。但通常省略

#include <iostream>
//定义fun函数
void fun(void)
{
 std::cout << "xzx" << std::endl;//大括号里面是函数体
}
int main()//mian函数比较特殊。他是程序的入口,main函数里面可以通过“函数名”来搜索想要调用的函数{
 fun();//在mian函数里面调用fun函数
}

在这里插入图片描述
形参列表可以无形参变量

形参列表中有两个形参,但第二个形参 int 我们没有给他名称,在fun函数里面我们没办法获取这个形参所对应的实参值。但这样可以保证main函数调用fun函数时,接口还是fun(“xxx”, 0)的形式,接口不变。在mian函数里面调用fun函数,把实参"Hello World"赋给形参pInfo,但无法把实参0赋给fun函数中的另一个形参(因为它没有名称,在fun函数里面我们没办法获取这个形参所对应的实参值)。

#include <iostream>
//定义fun函数
void fun(const char* pInfo, int)//形参列表中有两个形参,但第二个形参我们没有给他名称,在fun函数里面我们没办法获取这个形参所对应的实参值。但这样可以保证main函数调用fun函数时,接口还是fun("xxx", 0)的形式,接口不变。
{
 std::cout << pInfo << std::endl;//大括号里面是函数体
 return;//这么写也可以。表示从fun函数中退出,但没返回值。但return 0;就不行
}
int main()//mian函数比较特殊。他是程序的入口,main函数里面可以通过“函数名”来搜索想要调用的函数
{
 fun("Hello World", 0);//在mian函数里面调用fun函数,把实参"Hello World"赋给形参pInfo
 fun("Hello xzx", 9);//一个函数是可以被反复调用的
}

函数体

包含了函数具体的执行逻辑。

main函数

main函数是特殊的函数,作为整个程序的入口。操作系统在调用c++程序时,最开始调用的函数就是main函数。

int main()
 fun("Hello World", 0);
 fun("Hello xzx", 9);
 return 0;  //通常使用0来表示正常返回,0返回给操作系统}

c++定义函数时不加void的话,都需在函数体最后写return,但main函数例外,可以不写,默认return 0。其次main函数的返回类型一定是int,表示程序的返回值。通常使用0来表示正常返回。

形参列表可以为空(main函数的形参列表要么为空,要么为:int, char []*)

int main(int argc, char* argv[])//表示两个形参
{
 fun("Hello World", 0);
 fun("Hello xzx", 9);//一个函数是可以被反复调用的 return 0;
}

形参名称可变,但类型不能变

int main(int a, char* r[]){  //形参名称可变,但类型不能变
 fun("Hello World", 0);
 fun("Hello xzx", 9);//一个函数是可以被反复调用的
 return 0;
}

形参名称没有也可以,形参类型在就行

int main(int, char* []){  //形参名称没有也可以,形参类型在就行
 fun("Hello World", 0);
 fun("Hello xzx", 9);//一个函数是可以被反复调用的
 return 0;
}

内建类型

(内建)类型可为一段存储空间赋予实际的意义。我们熟知的基本数据类型也属于内置类型,如int, byte等(byte占一个字节,int占4个字节)。
在这里插入图片描述
那么,我们如何来引用这些数据呢?以下面代码为例,我们通过pInfo,pValue来引用内存中所定义的某一块字节,从而获取数据。如 fun(“Hello World”,0) 中的fun传入 “Hello World”,0 之后,系统会找一段内存来存储"Hello World",再找另外一段内存来存储0,再使用pInfo,pValue来引用这段内存。

#include <iostream>
//定义fun函数
void fun(const char* pInfo, int pValue )//const char* pInfo是一个形参,const char*指定了pInfo类型。int pValue 是另一个参数,参数之间用逗号划分
{
 std::cout << pInfo << std::endl;//大括号里面是函数体
 return;//这么写也可以。表示从fun函数中退出,但没返回值。但return 0;就不行
}
int main()//mian函数比较特殊。他是程序的入口,main函数里面可以通过“函数名”来搜索想要调用的函数
{
 fun("Hello World",0);//在main函数里面调用fun函数,把实参"Hello World"赋给形参pInfo
 fun("Hello xzx",9);//一个函数是可以被反复调用的
}

语句

C++程序是一组数组,而每个数组又是一组语句。语句表明了需要执行的操作。

主要可划分为:表达式+分号(以分号作为结束)的语句、语句块、if/while等语句。

注释

会被编译器忽略的内容(用于编写说明或去除不使用的语句)。它有两种注释形式:/**/ 与//

2. 系统I/O

2.1. iostream

iostream是标准库所提供的IO接口,用于与用户交互。我们可以使用 #include < iostream > 这个头文件实现系统IO(头文件通过include来引用)。

2.1.1. #include “”和#include < >的区别

如果使用#include “”,系统会从当前目录开始寻找头文件。如:#include “myheader.h”,系统会在write helloworld.cpp所在的头文件目录下寻找myheader.h。
在这里插入图片描述
如果使用#include <>,系统会从操作系统的环境变量所指示的路径寻找头文件。

2.1.2. 输入流

cin;(用户键盘输入)

2.1.3. 输出流

cout / cerr / clog(通常输出到屏幕上)

输入流、输出流在程序中的简单使用如下:

#include <iostream>
int main()
{
 int x;
 std::cout << "How old are you:"; std::cin >> x;
 std::cout << "You are" << x;
}

在这里插入图片描述

2.1.4. 输出流的区别:

输出目标不同(cerr输出的是错误信息);

是否立即刷新缓冲区

cerr 和 clog的区别:cerr输出的是错误信息,我们需要尽快的看到这些信息,从而使我们能更加全面的对系统进行了解,故cerr会立即刷新缓存区。但clog是日志信息,采用的是不立即刷新缓存区的方式。

如果我们想立即看到我们打印的东西,但没看到打印输出时,可能是缓冲区没有被刷新。那应该咋办?

一方面,可以使用cerr,cerr只要往外输出了,就刷新缓存区了。

另一方面,若使用cout或clog时也想刷新缓存区(使用cout时,是在程序结束时才刷新缓存区),则可通过std::fush ; 或std::endl来刷新缓存区。

如:

#include <iostream>
int main()
{
 std::cout << "output from cout" << std::flush;}

在执行到flush时,就会刷新缓存区。这样就能保证程序执行完这条语句之后, “output from cout” 这个信息就已经能被终端用户所看到。
在这里插入图片描述
而如果使用std::endl,不仅会刷新缓存区,还会换行:
在这里插入图片描述
但一般只有在必要时才刷新缓存区。

2.2. 名字空间

在C/C++中,变量、函数和类都是大量存在的,这些变量、函数、类的名称都将作用于全局作用域中,可能会导致很多的冲突。所以,C++中引入namespace关键字,目的是对标识符的名称进行本地化,以避免命名冲突或名字污染

2.2.1. 如何设置namespace?

namespace NameSpace1 //NameSpace1 就是我们定义的一个名字空间的名称

2.2.2. 如何在函数中调用名字空间中的函数?

如:main函数中如何调用名字空间中的fun函数?如果在main函数中,想调用NameSpace1 中的fun函数,像以下代码这么写,系统会认为是在全局名字空间中调用fun函数,但实际上全局名字空间中并没有fun函数。而且也不知道想调用的是NameSpace1 中的fun还是NameSpace2中的fun。

#include <iostream>
namespace NameSpace1 
{ 
 void fun( )
 { }
}
namespace NameSpace2
{
 void fun()
 { }
}
int main()
{
 fun( );//这么写的话,系统会认为是在全局名字空间中调用fun函数,但实际上全局名字空间中并没有fun函数
}

其实,访问名字空间中元素的 3 种方式:域解析符 ::using 语句名字空间别名

域解析符 ::

使用域解析符 ::,在main函数在调用NameSpace1中的fun函数。

#include <iostream>
namespace NameSpace1 
{ 
 void fun( )
 { }
}
namespace NameSpace2
{
 void fun()
 { }
}
int main()
{
 NameSpace1::fun( );//使用域解析符 ::,在main函数在调用NameSpace1中的fun函数。
}

使用域解析符 ::,在main函数在调用NameSpace2中的fun函数。

#include <iostream>
namespace NameSpace1 
{ 
 void fun( )
 { }
}
namespace NameSpace2
{
 void fun()
 { }
}
int main()
{
 NameSpace2::fun( );
}

using 语句

使用using namespace NameSpace1,在main函数内部,既能看到全局名字空间里所有函数,又能看到NameSpace1里面所有的函数。此时再去调用fun函数,首先会在全局名字空间里查找fun函数,如果全局名字空间里没有fun,再去NameSpace1查找。

#include <iostream>
namespace NameSpace1 
{ 
 void fun( )
 { }
}
namespace NameSpace2
{
 void fun()
 { }
}
int main()
{
 using namespace NameSpace1;//在main函数内部,既能看到全局名字空间里所有函数,又能看到NameSpace1里面所有的函数
 fun();//这时,首先会在全局名字空间里查找fun函数,如果全局名字空间里没有fun,再去NameSpace1查找。
}

名字空间别名

为NameSpace1这个名字空间赋予一个简单的别名ns1,然后再使用类似域解析符的方式调用fun函数。

#include <iostream>
namespace NameSpace1 
{ 
 void fun( )
 { }
}
namespace NameSpace2
{
 void fun()
 { }
}
int main()
{
 namespace ns1 = NameSpace1;//为NameSpace1这个名字空间赋予一个简单的别名ns1
 ns1::fun();//别名空间调用fun函数
}

2.2.3. std 名字空间

std 是c++标准库里的名字空间。

std::cout << "output from cout" << std::flush;

如,cout函数,flush函数都包含在std这个名字空间里。访问名字空间中的变量和访问名字空间中的函数方法是同样的操作。

2.2.4. 名字空间与名称改编( name mangling )

从上一章我们知道,整个程序编译完之后会编译出.o文件,再链接成可执行文件。

假设有这么个程序:

#include <iostream>
namespace NameSpace1 
{ 
 void fun( )
 { }
 int x;
}
namespace NameSpace2
{
 void fun()
 { }
}
int main()
{
}

我们来看一下编译完是什么样?
在这里插入图片描述
其中,HelloWorld* 是可执行程序(链接后的结果),main.cpp.o是编译后的结果。我们使用nm命令罗列main.cpp.o所有外部链接(链接:比如说,我要在一个目标文件里想要调用fun1,而第二个目标文件里有fun1的定义,我们就要把这两个目标文件链接起来):
在这里插入图片描述
T main函数是一个外部链接,B _ZN10NameSpace11xE是整型变量x的链接名称。T _ZN10NameSpace13funEv是NameSpace1中fun的链接名称,T _ZN10NameSpace23funEv是NameSpace2中fun的链接名称。

我们在源代码中的NameSpace1和NameSpace2中定义了fun函数和x变量,但在外部链接中没有找到fun和x,为什么呢?

因为,NameSpace1和NameSpace2都有fun,这是两个不同的fun定义,都需要对外提供链接,即提供两个不同的链接。故不能把两个不同的链接名字都叫fun,如果都叫fun,就没办法区别这两个不同的链接了,故c++内部会引入mangling机制,会对fun的链接名称自行改编。

我们可把链接名字变回去:
在这里插入图片描述

2.3. C / C++ 系统IO比较

printf: 使用直观,但容易出错

cout: 不容易出错,但书写冗长

C++ 20格式化库:新的解决方案(把一段内容解析成字符串,但很多编译器未支持)

#include <iostream>
#include <cstdio>  //引用#include <cstdio>头文件,再去使用printf(c语言的操作)
int main( )
{
 int x = 9;
 std::cout << "I have " << x << " pens\n";//c++的输出,如果改成float x = 9,std也会自动匹配输出相应的数据类型
printf("I have %d pens\n", x);//c语言的输出,%d是一个整数占位符,后面会用x替换掉占位符
}

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-24 11:15:53  更:2021-07-24 11:18:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/7 21:58:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码