同調実験室 - ARGIUS.net

TOP PAGE INDEX Number / 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

10:値渡しと参照渡し

機能

参照渡し(ポインタ渡し)をすると、関数(メソッド)側で値を変更できる

  1. 値を定義する
  2. 実行前の値を表示する
  3. 関数(メソッド)1を値渡しで呼び出す
  4. 実行後の値を表示する
  5. 関数(メソッド)2を参照(ポインタ)渡しで呼び出す
  6. 実行後の値を表示する
以下の言語では、仕様として制限があるため、代替手段を使う

※Javaではプリミティブ型を参照で渡せない
※RubyではNumericオブジェクトはimmutableのため参照先で更新できない

実行結果

$ ./test
メイン     : 5
関数1の中 : 6
メイン     : 5
関数2の中 : 6
メイン     : 6

$

ソース

C

#include <stdio.h>

/* 関数1 */
void do_function_by_value(int x)
{
  ++x;
  printf("関数1の中 : %d\n", x);
}

/* 関数2 */
void do_function_by_reference(int *x)
{
  ++*x;
  printf("関数2の中 : %d\n", *x);
}

int main()
{
  /* intを5に設定 */
  int a = 5;
  
  /* 実行前の値を表示 */
  printf("メイン     : %d\n", a);
  
  /* 関数1を実行(値渡し) */
  do_function_by_value(a);
  
  /* 関数1実行後の値を表示 */
  printf("メイン     : %d\n", a);
  
  /* 関数2を実行(ポインタ渡し) */
  do_function_by_reference(&a);
  
  /* 関数2実行後の値を表示 */
  printf("メイン     : %d\n", a);
  
  return 0;
}

C++

#include <iostream>

// 関数1
void do_function_by_value(int x)
{
  ++x;
  std::cout << "関数1の中 : " << x << std::endl;
}

// 関数2
void do_function_by_reference(int& x)
{
  ++x;
  std::cout << "関数2の中 : " << x << std::endl;
}

int main() {
  
  /* intを5に設定 */
  int a = 5;
  
  /* 実行前の値を表示 */
  std::cout << "メイン     : " << a << std::endl;
  
  /* 関数1を実行(値渡し) */
  do_function_by_value(a);
  
  /* 関数1実行後の値を表示 */
  std::cout << "メイン     : " << a << std::endl;
  
  /* 関数2を実行(参照渡し) */
  do_function_by_reference(a);
  
  /* 関数2実行後の値を表示 */
  std::cout << "メイン     : " << a << std::endl;
  
  return 0;
}

Java

// 参照のためのクラス
class PrimitiveIntegerHolder {
    
    public int value = 0;
    
}

class Main {
    
    // 関数1
    static void doFunctionByValue(int x) {
        
        ++x;
        System.out.println("関数1の中 : " + x);
        
    }
    
    // 関数2
    static void doFunctionByReference(PrimitiveIntegerHolder obj) {
        
        ++obj.value;
        System.out.println("関数2の中 : " + obj.value);
        
    }
    
    public static void main(String[] args) {
        
        /* intを5に設定 */
        int a = 5;
        
        /* 実行前の値を表示 */
        System.out.println("メイン     : " + a);
        
        /* メソッド1を実行(値渡し) */
        doFunctionByValue(a);
        
        /* 実行前の値を表示 */
        System.out.println("メイン     : " + a);
        
        /* メソッド2を実行(参照渡し) */
        PrimitiveIntegerHolder holder = new PrimitiveIntegerHolder();
        holder.value = a;
        doFunctionByReference(holder);
        
        /* メソッド2実行後の値を表示 */
        System.out.println("メイン     : " + holder.value);
        
    }
    
}

Perl

# 関数1
sub do_function_by_value {
    
    my $x = $_[0];
    ++$x;
    print"関数1の中 : $x\n";
    
}

# 関数2
sub do_function_by_reference {
    
    my $x = $_[0];
    ++$$x;
    print"関数2の中 : $$x\n";
    
}

#
# main
#

# intを5に設定
my $a = 5;

# 実行前の値を表示
print"メイン     : $a\n";

# 関数1を実行(値渡し)
&do_function_by_value($a);

# 関数1実行後の値を表示
print"メイン     : $a\n";

# 関数2を実行(参照渡し)
do_function_by_reference(\$a);

# 関数2実行後の値を表示
print"メイン     : $a\n";

Ruby

class IntegerHolder
  def initialize(n)
    @value = n
  end
  def change!(n)
    @value = n
  end
  def +(n)
    @value += n
  end
  def value
    return @value
  end
end

# 関数1
def call(x)
  x += 1
  puts "関数1の中 : #{x}"
end

# 関数2
def call!(x)
  x.change!(x + 1)
  puts "関数2の中 : #{x.value}"
end

# intを5に設定
a = 5

# 実行前の値を表示
puts "メイン     : #{a}"

# 関数1を実行(値渡し)
call(a)

# 関数1実行後の値を表示
puts "メイン     : #{a}"

# 関数2を実行(参照渡し)
xa = IntegerHolder.new(a)
call!(xa)

# 関数2実行後の値を表示
puts "メイン     : #{xa.value}"

最終更新日 : 2004.08.23

TOP PAGEINDEX Number / 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18