C++中的参数类型


数组

数组是相同类型数据的集合。引入数组就不需要在程序中定义大量的变量,大大减少程序中变量的数量,使程序精炼,而且数组含义清楚,使用方便,明确地反映了数据间的联系。许多好的算法都与数组有关。熟练地利用数组,可以大大地提高编程的效率,加强程序的可读性。

一个数组在内存中占用的存储单元是连续的,也就是说一个数组在内存中占用一片连续的存储单元。在32位的机器上,一个int类型的值占4Byte,如果a[0]的地址是2000,那么a[1]的地址就是2004,a[2]的地址就是2008,a[3]的地址就是2012……如此类推。

strlen()与sizeof()的区别如下所示:

  • strlen()是函数,在运行时才能计算。参数必须是字符型指针(char*),且必须是以'\0'结尾的。当数组名作为参数传入时,实际上数组已经退化为指针了。它的功能是返回字符串的长度。
  • sizeof()是运算符,而不是一个函数,在编译时就计算好了,用于计算数据空间的字节数。因此,sizeof不能用来返回动态分配的内存空间的大小。sizeof常用于返回类型和静态分配的对象、结构或数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系。

指针

数据在内存中的存储:如果在程序中定义了一个变量,在编译时就给这个变量分配内存单元。系统根据程序中定义的变量类型,来分配一定长度的空间。例如,C++编译系统在32位机器上为整型变量分配4Byte,为单精度浮点型变量分配4Byte,为字符型变量分配1Byte。内存区的每一个字节有一个编号,这个编号就是地址。程序经过编译以后已经将变量名转换为变量的地址,对变量值的存取都是通过地址进行的。

这种按变量地址存取变量值的方式称为直接存取方式,或直接访问方式。还可以采用另一种称为间接存取(间接访问)的方式,在程序中定义一种特殊的变量,专门用来存放地址。由于通过地址能找到所需的变量单元,因此可以说,地址指向该变量单元。因此将地址形象化地称为“指针”,一个变量的地址称为该变量的指针。如果有一个变量是专门用来存放另一变量地址(即指针)的,则它称为指针变量。指针变量的值(即指针变量中存放的值)是地址(即指针)。

指针也是一种变量,普通的变量存放的是实际的数据,而指针变量包含的是内存中的一块地址,这块地址指向某个变量或者函数。指针的内容包括:指针的类型、指针所指向的类型、指针的值以及指针本身所占的内存区。

数组与指针:

数组指针,也称行指针,假设有定义int(*p)[n];且()优先级高,首先说明p是一个指针,且指向一个整型的一维数组。这个一维数组的长度是n,也可以说是p的步长,也就是说执行p+1时,p要跨过n个整型数据的长度。

指针数组,假设有定义int*p[n];且[ ]优先级高,可以理解为先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里若执行p+1操作则是错误的,p=a这样赋值也是错误的,因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量,只用来存放变量地址。但可以这样*p=a赋值,这里*p表示指针数组第一个元素的值,a的首地址的值。

数组指针和指针数组两者的区别:

  • 数组指针只是一个指针变量,可以认为是C语言里专门用来指向二维数组的,它占用内存中一个指针的存储空间;
  • 指针数组是多个指针变量,以数组形式存在内存当中,占用多个指针的存储空间。还需要说明的一点就是,同时用来指向二维数组时,其直接引用和用数组名引用都是一样的。

字符串与指针:

(1)字符串指针变量本身是一个变量,用于存放字符串的首地址。定义指针时,编译器并不为指针所指向的对象分配空间,它只是分配指针本身的空间。

(2)字符串本身是存放在以该首地址为首的一块连续的内存空间中,并以'\0'作为字符串的结束标志。

(3)字符数组是由于若干个数组元素组成的,每个元素中存放字符串的一个字符。在定义一个字符数组时,编译后就会分配一个内存单元,每个元素都有确定的地址。

函数与指针:

函数指针是指向函数的指针变量。所以,函数指针首先是个指针变量,而且这个变量指向一个函数。C++在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,就可以用该指针变量调用函数了。

函数指针的声明方法是:

返回值类型 (*指针变量名)([形参列表]);

其中,返回值类型说明函数的返回值类型,(*指针变量名)这句的括号不能省略。


引用

引用是一种变量类型,它用于为一个变量起一个别名。

引用的声明方法是:

类型标识符 &引用名=目标变量名;

定义引用r,它是变量a的引用,即别名。经过这样的声明后,a和r的作用都一样,都代表着同一变量。a和r占用内存的同一个存储单元,即具有同一地址。在声明一个引用变量时,必须同时使之初始化,即声明它代表哪个变量。函数执行期间,不可以将其再作为其他变量的引用。

引用一个重要的作用就是作为函数的参数。


引用作为函数的参数举例:

#include<iostream>

using namespace std;

void Mmin1(int a,int b)

{

int temp;

if(a>b)

{

temp=a;

a=b;

b=temp;

}

}

void Mmin2(int &a,int &b)       // 引用作为函数的参数

{

int temp;

if(a>b)

{

temp=a;

a=b;

b=temp;

}

}

int main()

{

int a=30,b=20;

Mmin1(a,b);

cout<<a<<" "<<b<<endl;       // a、b的值保持不变。

Mmin2(a,b);

cout<<a<<" "<<b<<endl;      // a的值是20,b的值是30. a、b的值被修改了

return 0;

}

程序的执行结果是:

30 20

20 30


将一般变量作为函数的参数,传给形参的是变量的值,传递是单向的。如果在执行函数期间形参的值发生变化,并不传回给实参。因为在调用函数时,形参和实参不是同一个存储单元。

使用引用传递函数的参数时,在内存中并没有产生实参的副本,而是对实参直接操作。当使用一般变量传递函数的参数时,当函数发生调用,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率更高,所占空间更少。

使用指针作为函数的参数虽然也能达到与使用引用同样的效果,但是在被调函数中同样要给形参分配存储单元,且需要重复使用“*指针变量名”的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参,这些都不太方便。

常引用

如果既要提高程序的效率,又要使传递给函数的数据不在函数中被改变,就应该使用常引用。

常引用的声明方式是:

const 类型标识符 &引用名=目标变量名;

用这种方式声明的引用,不能通过引用对目标变量的值进行修改,在程序中使引用的目标成为const类型,从而保证了引用的安全性。

C++中的参数类型的更多相关文章

  1. 如何将C++中的SOCKADDR_IN*参数类型转换成C#中的参数类型

    将C++中的参数类型SOCKADDR_IN*映射为C#中的IntPtr参数类型的示例代码如下: IntPtr ptrSockaddr = new IntPtr(); //ip地址 sockaddr_i ...

  2. python-函数中的参数类型和可变参数解析

    最近,在学习python,天天抱着廖雪峰的教材苦练,https://www.liaoxuefeng.com/ 但廖老毕竟是如此的才华盈溢,我这等小辈真是读起来教程都有些费力. 关于python-函数中 ...

  3. C# 方法中的参数类型

    二.方法中的参数类型 1. 值参数 值参数是指不带修饰符只带数据类型的形参. 值参数在使用值向方法传递参数时,编译程序会把实参的值做一份拷贝,并且将此拷贝传递给该方法,被调用的方法不会修改内存中实参的 ...

  4. Python中函数参数类型和参数绑定

    参数类型 Python函数的参数类型一共有五种,分别是: POSITIONAL_OR_KEYWORD(位置参数或关键字参数) VAR_POSITIONAL(可变参数) KEYWORD_ONLY(关键字 ...

  5. 对Python中函数参数类型及排序问题,三个方面的总结

    Python中函数的参数问题有点复杂,主要是因为参数类型问题导致的情况比较多,下面来分析一下. 参数类型:缺省参数,关键字参数,不定长位置参数,不定长关键字参数. 其实总共可以分为 位置参数和关键字参 ...

  6. python函数中的参数类型

    python函数中的参数 动态获取函数的参数 python的函数类型详解

  7. 在之前的EventHandler中的参数类型必须继承EventArgs,现在已经去掉这个约束了。

    分别是vs2008和vs2012的对比,可以看到2012已经去掉了约束条件.

  8. 11、mybatis的映射xml中参数类型的别名

    在mapper.xml中,定义很多的statement,statement需要parameterType指定输入参数的类型.需要resultType指定输出结果的映射类型. 如果在指定类型时输入类型全 ...

  9. 关于mybatis的参数2个使用经验(类似于struts2的通配所有页面的action配置,xmlsq语句参数类型为基本类型时的快捷指定办法)

    1.我们都知道在struts2中为防止浏览器绕过struts过滤器直接请求页面,所以我们都会配置一个拦截所有页面的action,如下: <action name="*"> ...

随机推荐

  1. GMOJ5409.【GDOI2017模拟一试4.11】平行宇宙

    https://gmoj.net/senior/#main/show/5051 Solution 首先注意到每个点有且只有一条出边,也就是说这是一个环套树(森林). 那么我们可以贪心. 首先这个森林里 ...

  2. Java面向对象入门(2)-访问修饰符

    Java访问修饰符–public, protected, private and default Java提供了四个访问修饰符来设置类,变量,方法和构造函数的访问级别,即public,private, ...

  3. MySQL基础(7) | 触发器

    MySQL基础(7) | 触发器 基本语法 创建 CREATE TRIGGER trigger_name trigger_time trigger_event ON table_name FOR EA ...

  4. 安装NFS到CentOS(YUM)

    运行环境 系统版本:CentOS Linux release 7.3.1611 软件版本:无 硬件要求:无 安装过程 1.配置YUM源 [root@localhost ~]# rpm -i https ...

  5. Fight Against Monsters Gym - 102222H【贪心】

    贪心的策略 #include <bits/stdc++.h> using namespace std; ; typedef long long ll; struct m { int hp, ...

  6. final 和 static之间的区别和联系

    关键字final和关键字static两者的含义并不相似,但是笔者常常使用一段时间后就会忘记它们之间的区别,因为它俩总是相伴着出现.当只出现其中一个时,就对其代表的含义不甚清晰了.故而特地将相关知识点记 ...

  7. Python 测试代码 初学者笔记

    单元测试 每完成一个单元测试,Python都会打印一个字符: 测试通过打印一个句点:测试引发错误打印E:测试导致断言失败打印F 模块unittest import unittest from name ...

  8. Open Live Writer(olw)博客写作软件

    前言 wlw似乎不再提供下载了,从微软的官网下载安装程序之后,无法联网下载olw组件,所以写博客改用olw. olw是wlw的开源版本,所以wlw上的操作是可以在olw上继续使用的. 关于wlw的知识 ...

  9. gulp常用插件之gulp-plumber使用

    更多gulp常用插件使用请访问:gulp常用插件汇总 gulp-plumber这是一款防止因gulp插件的错误而导致管道中断,plumber可以阻止 gulp 插件发生错误导致进程退出并输出错误日志. ...

  10. Codeforces Round #624 (Div. 3) F. Moving Points 题解

    第一次写博客 ,请多指教! 翻了翻前面的题解发现都是用树状数组来做,这里更新一个 线段树+离散化的做法: 其实这道题是没有必要用线段树的,树状数组就能够解决.但是个人感觉把线段树用熟了会比树状数组更有 ...