【C++编程基础】(1)—— 函数原型声明、函数模板、引用、const 常引用、const 常量指针
一、函数原型声明:
1、函数声明告诉编译器函数的名称,和如何调用函数(返回类型和参数);函数定义提供了函数的实际主体。
2、强制性的:在C++中,如果函数调用的位置在函数定义之前,则要求在函数调用之前必须对所调用的函数作函数原型声明。
3、在函数声明中,参数名称并不重要,只有参数类型是必须的。即下述两种写法都被允许:
int max(int x,int y);
int max(int,int);
4、当函数定义 (func.cpp) 与代码主体 (main.cpp) 分开时,在 main.cpp 中添加 #include "func.cpp" 即可直接在代码主体文件中不作声明地调用函数。
二、函数模板
1、类型的参数化:①众所周知,数据的值可以通过函数参数传递,在函数定义时数据的值是未知的,只有等到函数调用时接收了实参才能确定其值。
②同样的,数据的类型也可通过参数传递。在函数定义时不指明具体的数据类型,当发生函数调用时,编译器根据传入的实参自动推断数据类型。
2、所谓函数模板,实际上是建立一个通用函数,它所用到的数据的类型(包括返回值类型、形参类型、局部变量类型)可以不具体指定,而是用一个虚拟的类型来代替(实际上是用一个标识符来占位),等发生函数调用时再根据传入的实参来逆推出真正的类型。这个通用函数就称为函数模板(Function Template)。
#include <iostream>
using namespace std; //通用函数定义
template<typename T1>
T max(T a,T b,T c)
{
if (b>a) a=b;
if (c>a) a=c;
return a;
}
3、同样的,可以根据需要来确定类型参数的个数:
template<typename T1, typename T2 >
三、引用
1、形参:如果函数要使用参数,则必须声明接收参数值的变量。这些参数成为函数的形式参数。形式参数就像其他在函数内声明的局部变量一样,进入函数时创建,退出函数时销毁。
2、调用函数时,有两种向函数传递参数且运行后能传回给实参的方法:
①指针调用:把参数的地址复制给形参;②引用调用:把参数的引用复制给形参。
*传值调用不会影响实参。它只是一种单向的传递,将实参值传给了形参。
3、在C++中,变量的“引用”就是变量的别名,因此引用又称为别名 (alias) 。
引用写法: 类型名 & 引用名 = 同类型的某变量名;
int n=;
int& r = n; //声明r是一个整形变量的引用变量,它被初始化为n
cout << r; //得到40
# r 就是一个引用,也可以说r的类型是 int &
4、对变量声明一个引用,并不另开辟内存单元,r 和 n 都代表同一变量单元。
5、在声明一个引用时,必须同时使之初始化:通常用变量去初始化引用;也可以用引用去初始化引用;最后也可以用表达式的返回值为某变量的表达式去初始化引用,如下:
//引用作为函数的返回值
int n=;
int& SetValue() {return n;}
int main()
{
SetValue() = ;
cout << n; //输出90
return ;
}
这里解释一下第三行:SetValue() 函数的返回值类型是 int&,即返回值类型是个引用;而返回值是n,即 SetValue() 返回值是一个对 n 的引用。
返回值为引用的优点是可以将其放置在等号的左边,具体作用将来碰到再讲。
四、const常引用:用 const 对引用加以限定。
int i=;
const int& a = i; //声明常引用
a = ; //尝试通过常引用 a 修改 i 的值,报错
常引用不能通过引用去修改原变量的值,但原变量自己可以变化。
五、const 常量指针
1、定义常量指针: const 类型名* 指针变量名;
2、常量指针中,指针指向的内容不可改变。不可以通过常量指针修改其指向的内容,但可以修改指针的指向。
int n,m;
const int* p = &n;
*p = ; //编译出错,不能修改指向的内容
n = ; //ok,指向的内容自身可以变化
p = &m; //常量指针的指向可以变化
4、常量指针不能赋值给非常量指针,反之可以(不推荐):
const int* p1;
int* p2;
p1 = p2; //ok
p2 = p1; //error
p2 = (int* )p1; //ok, 强制类型转换
非常量指针(可改)获得了常量指针(不可改)的指向,就可以修改 const 指针指向的值,但大多数情况下 const 指针的指向值倾向于不被修改。
5、常量指针能保护常变量的值:
void MyPrintf(const char* p)
{
strcpy(p, "this"); //编译出错
printf("%s", p); //ok
}
strcpy()函数期待一个 char* 变量,而p在这里是一个const char* 变量,故编译错误。常量指针保护了 p 不被修改。
【C++编程基础】(1)—— 函数原型声明、函数模板、引用、const 常引用、const 常量指针的更多相关文章
- c++函数内部声明函数,在函数外面实现函数是可以的
这个具体有什么用我也不大清楚,只知道可以这样 #include <iostream> //#include "header1.h" using namespace st ...
- 【C编程基础】C程序常用函数
基础知识 1.const const 修饰的数据类型是指常类型,常类型的变量或对象的值是不能被更新的. ; 或 ; //在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再改变它了 ...
- C++学习7-面向对象编程基础(多态性与虚函数、 IO文件流操作)
多态 多态性是指对不同类的对象发出相同的消息将返回不同的行为,消息主要是指类的成员函数的调用,不同的行为是指不同的实现: 函数重载 函数重载是多态性的一种简单形式,它是指允许在相同的作用域内,相同的函 ...
- 第七节,TensorFlow编程基础案例-TensorBoard以及常用函数、共享变量、图操作(下)
这一节主要来介绍TesorFlow的可视化工具TensorBoard,以及TensorFlow基础类型定义.函数操作,后面又介绍到了共享变量和图操作. 一 TesnorBoard可视化操作 Tenso ...
- 关于gcc编译器中函数不用进行原型声明的解释
经过大量实验和参考网上的说法得出一个结论: gcc编译器中,函数可以不用提前进行原型声明,编译器会把函数调用同时认为是声明.需要注意的是,由于函数调用的时候并没有写明函数返回值,这是gcc把调用当成声 ...
- 网络编程readn、writen和readline函数的编写
readn 在Linux中,read的声明为: ssize_t read(int fd, void *buf, size_t count); 它的返回值有以下情形: 1.大于0,代表成功读取的字节 ...
- WebKit 内核浏览器 initKeyboardEvent 函数原型
学习JS发送自定义键盘(KeyboardEvent)事件的过程中,遇到了一个小难题:单个按键Tab可以正常发送,焦点能够转移到下一个元素,但想实现Shift+Tab,反向移动焦点时,却被DOM3的浏览 ...
- (C语言)memcpy函数原型的实现
在网上看到一道题,实现一个memcpy函数,于是查了一下memcpy的函数原型,如下: void* memcpy(char *strDest, const char *strSrc, int Coun ...
- Linux open() 一个函数,两个函数原型
open在手册中有两个函数原型, 如下所示: int open(const char *pathname, int flags); int open(const char *pathname, int ...
随机推荐
- py 包和模块,软件开发目录规范
目录 py 包和模块,软件开发目录规范 什么是包? 什么是模块? 软件开发目录规范 py 包和模块,软件开发目录规范 什么是包? 包指的是内部包__init__.py的文件夹 包的作用: 存放模块,包 ...
- 洛谷P3063 [USACO12DEC]牛奶的路由Milk Routing
链接 其实在博客园里写题解都挺应付的都是在洛谷写了之后 挑一部分粘过来 在洛谷写的也都是废话,是为了凑篇幅 主要就是代码 大体思路就一提 这题贪心不行废话 跑m遍SPFA更新最小值 注意数组记得清空 ...
- 从零和使用mxnet实现dropout
需求: 从零和使用mxnet实现dropout 数据集: 使用load_digits()手写数字数据集 要求: 使用1个掩藏层n_hidden1 = 36,激活函数为relu,损失函数为softmax ...
- django数据请求
目录 数据请求: 静态文件加载 form表单 : 数据请求: request方法: 数据请求: 静态文件加载 静态文件加载: 1.默认情况下所有的html文件都是放在templates文件夹内 静态文 ...
- vue工具 - vue/cli@3.xx 安装使用流程
mac安装记得npm前边加sudo 安装脚手架,用于生成目录 npm install -g @vue/cli 安装用于编译单个的.vue文件 npm install -g @vue/cli-servi ...
- python: int to unicode string
>>> import types >>> print type(str(2)) <type 'str'> >>> ')) <ty ...
- Prometheus 介绍
我们知道zabbix在监控界占有不可撼动的地位,功能强大.但是对容器监控显得力不从心.为解决监控容器的问题,引入了prometheus技术.prometheus号称是下一代监控.接下来的文章打算围绕p ...
- 在RedisTemplate中使用scan代替keys指令
keys * 这个命令千万别在生产环境乱用.特别是数据庞大的情况下.因为Keys会引发Redis锁,并且增加Redis的CPU占用.很多公司的运维都是禁止了这个命令的 当需要扫描key,匹配出自己需要 ...
- 算法:线性查找(重点isFlag标志)
package com.atguigu; public class Main { public static void main(String[] args) { String[] arr=new S ...
- Java学习:等待唤醒机制
等待唤醒机制 线程的状态 NEW 至今尚未启动的线程处于这种状态 RUNNABLE 正在Java虚拟机中执行的线程处于这种状态 BLOCKED 受阻塞并等待某个监视器锁的线程处于这种状态 WA ...