C++与Java,C#的异同(一):值,地址,引用

Java,C#已经比较熟悉,最近在从0开始自学C++。学习过程中必然会与Java,C#进行对比,有吐槽,也有点赞。

先来讲讲最基本也是最重要的部分:参数传递的方式。

对于类型, Java分基本类型、复合类型,从另外一个角度分是值类型,引用类型。在展开对比前, 我们先来看看三个关键方式:

    • 创建新的副本,与原来的没有关系
  • 地址(指针)
    • 把对象所在内存的地址传递过去
  • 引用
    • 可以理解为变量的别名

举个例子:

 1 void testMethodA(int input) {
 2     input = 999;
 3 }
 4
 5 void testMethodB(int* input) {
 6     //int newValue = 888;
 7     *input = 888;
 8 }
 9
10 void testMethodC(int& input) {
11     input = 777;
12 }
13
14 int main() {
15
16     int input = 111;
17     cout << "Original: " << input << endl;
18     testMethodA(input);
19     cout << "After testMethodA: " << input << endl;
20     cout << input;
21     testMethodB(&input);
22     cout << "After testMethodB: " << input << endl;
23     cout << input;
24     testMethodC(input);
25     cout << "After testMethodC: " << input << endl;
26
27     std::cin.get();
28
29     // What is the value of input?
30
31 }

运行后的结果:

Original: 111
After testMethodA: 111
111After testMethodB: 888
888After testMethodC: 777

解释一下:

函数 testMethodA 的参数是值传递的,调用函数后,创建了一个input的副本,副本的值改变了, 但是input值没有被改变。

函数 testMethodB 的参数是地址(指针)传递的,函数内修改了input指向的那块内存区域,所以input的值也被改变了。

函数 testMethodC的行为看起来是和函数 testMethodB是一样的, input值也被改变了,他们有什么区别呢?

区别在于:

传递地址,函数内改变的是变量指向的那块内存区域的内容。

传递引用,函数内改变的是变量的指向,换句话说,input指向的内存地址都变了。

如下图:

在C++里面,所有的类型,不管是基础数据类型,结构体,还是类,默认都是“值”传递的;显式声明为指针,才是传地址;显式声明为引用,可以认为就是给变量起了一个别名。

在Java里面,只有基础数据类型(int, double, float等),是值传递的,所有的类对象,都是传地址(注意,不是传引用), 实际上,java里面没有引用传递的概念。

在C#里面, 基础数据类型,结构体, 默认都是值传递;所有的对象, 默认都是传地址;如果想传引用,在参数前面加ref关键字,例如:

1  void testMethodC(ref int input) {
2      input = 777;
3  }
时间: 2024-07-29 07:05:38

C++与Java,C#的异同(一):值,地址,引用的相关文章

atitit。全局变量的设计与实现 java php的异同

atitit.全局变量的设计与实现 java php的异同 1. 超级全局(Superglobals)"变量 1 2. 全局变量和"global"关键字 1 3. 更加好的方法  使用 $GLOBALS 替代 global 1 4. php和java的全局变量区别 2 5. 参考 2 1. 超级全局(Superglobals)"变量 PHP默认定义了一些"超级全局(Superglobals)"变量,这些变量自动全局化,而且能够在 程序的任何地方中

如何用java获得字符串的ASCII值

使用Integer.valueOf就可以直接将char类型的数据转为十进制数据表现形式. int value=Integer.valueOf('1');//49int value=Integer.valueOf('a');//97 如下所示: ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符.标准ASCII 码也叫基础ASCII码,使用7 位二进制数来表示所有的大写和小写字母,数字0 到9.标点符号, 以及在美式英语中使用的特殊控制字符.其中: 0-31及1

Java byte 类型的取值范围是-128~127

为什么Java byte 类型的取值范围是-128-127 : http://blog.163.com/[email protected]/blog/static/47517863200911314245752/ java基本数据类型的取值范围: http://www.cnblogs.com/singlesoar/p/5688915.html

java 数组中求最值

java中数组求最值,这在实际的开发中几乎用不到,但是在面试中会偶尔被问到,这是考你基本的思维能力,现在说下这个题的基本思路 思路: 1:先定义一个变量,一般是用数组的第一个值 2:在循环中判断(从第二个角标到数组的length-1角标对应的值)是否大于这个之前定义的值,如果大于那么就把这个值赋值给max,直到比完就可以求出最大值 代码如下: public static void main(String[] args) { int[] arr = {1,3,5,6,9,7}; int max =

java生成字符串的MD5值

下面的代码实现了MD5值的生成: public class MD5Test2 { public static void main(String[] args) { System.out.println(MD5Test2.MD5Operation("hello")); System.out.println(MD5Test2.getMD5("hello")); } //通过java.math包的BigInteger类实现十六进制的转换 public final stat

java 关于值引用、地址引用的问题

8种基本引用类型 四种整数类型(byte.short.int.long) 两种浮点数类型(float.double) 一种字符类型(char) 一种布尔类型(boolean) 以及如String, final类型的数据类型时. 在方法调用时,属于值传递,在方法中改变了值之后,原始值不会改变. 除了以上之外的数据类型,如自定义的对象,Map,List之类的引用,都是地址引用. 如下demo: import java.util.ArrayList; import java.util.HashMap;

java 正则获取html的值

对正则表达式不是很熟悉,最近做项目需要用到正则,一段html代码,例如<form><input name=\"test1\"    value=\"测试1\" ></input><input name=\"test2\"    value=\"测试2\" ></input></form> 需要获取test1对应的value的值: String source

spring:使用&lt;prop&gt;标签为Java持久属性集注入值

spring:使用<prop>标签为Java持久属性集注入值 使用 spring 提供的<prop>为Java持久属性集注入值,也就是向 java.util.Properties 对象中注入值. <props> 是简化了的 <map> ,该元素对应配置类型为 java.util.Properties 的对象依赖. 因为Properties 只能指定 String 类型的键和值,所以 <props> 的配置简化很多,只有固定的格式. 1.创建 Te

Java线程中带有返回值的线程Callable

在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了.现在Java终于有可返回值的任务(也可以叫做线程)了. 可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口. 执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了. 下面是个很简单的例子: package com.lyc import java.util.co

switch与java,c#的异同

<script type="text/javascript" language="javascript"> //JavaScript控制语句基本和以前学过的一样,switch有点特别(与C#类似,可以匹配字符串,java中不可以匹配字符串) var day = "星期日"; switch(day){  case "星期一":   document.write("工作日");    break;