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. 使用QT显示OpenCV读取的图片

    目录 1. 概述 2. 实现 2.1. 代码 2.2. 解析 3. 结果 1. 概述 OpenCV自带了一部分常用的GUI功能,但是更多的图像处理功能需要其他GUI框架来辅助实现,这里通过QT来显示O ...

  2. 插入数据失败提示: Setting autocommit to false on JDBC Connection 自动提交失败

    来源:https://blog.csdn.net/qq_42799475/article/details/102742109 今天在执行mybstis的测试时,明明已经写好了插入语句但是数据库没有插入 ...

  3. c# 异步编程总结

    异步编程前提 1.学委托 delegate 其中委托中的beginInvoke()和endInvoke()方法必须要会. 2.学习回调函数 (也可以不用,但是一般建议用回调函数中执行endinvoke ...

  4. STL专题

    一.algorithm 1.sort 问题1:给你n个整数,请按从大到小的顺序输出其中前m大的数. Input:每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二 ...

  5. Java语言与C++语言区别

    最近有点空闲时间,学习了Java语言.教材<Java简明教程>第四版,清华大学出版社.本人以前有C++基础,所以主要总结下两者区别. 一.基本类型和运算 1.布尔常量,true和false ...

  6. java使用原生MySQL实现数据的增删改查以及数据库连接池技术

    一.工具类及配置文件准备工作 1.1 引入jar包 使用原生MySQL,只需要用到MySQL连接的jar包,maven引用方式如下: <dependency> <groupId> ...

  7. 在线编辑器(WangEditor)

    自己之前写了一篇关于POI 相关的博客, 想了想在公司中一般常用的不就是上传下载,poi,分页,定时等.好像还有个在线编辑器, 于是自己就花了两个多小时把编辑器相关的代码撸了遍,当然了是先百度找了找资 ...

  8. Docke-ce 安装

    Docker-ce 的安装 安装系统工具 yum install -y yum-utils device-mapper-persistent-data lvm2 添加docker镜像源 yum-con ...

  9. linux(服务器)如何确认网卡(网口)对应的配置文件

    服务器装完系统就要配置网络,然而服务器经常是多网卡多网口,我们在某个网口插上网线后,到/etc/sysconfig/network-scripts/下配置ip时无法确定网口对应的配置文件.(比如是et ...

  10. CF566C Logistical Questions(10-1)

    题意 \(n\)个点的树,有点权,有边权,\(f(x)=\sum\limits_{i=1}^n w_idis(i,x)^{1.5}\),求最小的\(f(x)\)的\(x\) 单独考虑一条链,顺序编号, ...