【z88dk】C言語/関数(1) 引数の値渡しと参照渡し
初版 2026/02/09
改訂
func1.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// 値渡し
// 関数内の変数は同名でも呼び出し元に影響しない
// 内部的には引数の変数がスタックに確保され、関数の終了で破棄される
void testFunc_byVal(uint8_t value) {
value += 2;
}
// 参照渡し
// 与えられたポインタの値を直接更新するため、呼び出し元の変数の値にも反映される
// 対象のアドレスの値を直接操作するイメージ
void testFunc_byRef(uint8_t *value) {
*value += 2;
}
void main() {
uint8_t value = 5;
printf("by val\n");
testFunc_byVal(value);
printf("value = %d\n", value);
printf("by ref\n");
testFunc_byRef(&value);
printf("value = %d\n", value);
return;
}
- 関数の引数に変数名を指定すると、値渡しとなる。
- 関数の引数にポインタを指定すると、参照渡しとなる。
-
双方のアセンブリリストを比較すると、参照渡しにデコレータ
__z88dk_fastcallを付けても、値渡しの方が速いという結果となった(値渡しは、__z88dk_fastcallを付けると逆に遅くなった)。-
値渡し
呼び出し:42Tサイクル
40 0026 2a0000 ld hl,(_value) ; 7 40 0029 2600 ld h,0 ; 7 40 002b e5 push hl ; 11 40 002c cd0000 call _testFunc_byVal ; 17関数:86Tサイクル
15 ._testFunc_byVal 15 0000 210000 ld hl,2 ;const ; 7 15 0003 39 add hl,sp ; 11 15 0004 e5 push hl ; 11 15 0005 6e ld l,(hl) ; 7 15 0006 2600 ld h,0 ; 7 15 0008 23 inc hl ; 6 15 0009 23 inc hl ; 6 15 000a d1 pop de ; 10 15 000b 7d ld a,l ; 4 15 000c 12 ld (de),a ; 7 15 000d c9 ret ; 10 -
参照渡し
呼び出し:43Tサイクル
40 004a 210000 ld hl,_value ; 7 40 004d e3 ex (sp),hl ; 19 40 004e cd0e00 call _testFunc_byRef ; 17関数:110Tサイクル
23 ._testFunc_byRef 23 000e c1 pop bc ; 10 23 000f e1 pop hl ; 10 23 0010 e5 push hl ; 11 23 0011 c5 push bc ; 11 23 0012 e5 push hl ; 11 23 0013 6e ld l,(hl) ; 7 23 0014 2600 ld h,0 ; 7 23 0016 23 inc hl ; 6 23 0017 23 inc hl ; 6 23 0018 d1 pop de ; 10 23 0019 7d ld a,l ; 4 23 001a 12 ld (de),a ; 7 23 001b c9 ret ; 10関数にデコレータ
__z88dk_factcallを付与:87Tサイクル23 ._testFunc_byRef 23 000e e5 push hl ; 10 23 000f e5 push hl ; 10 23 0010 6e ld l,(hl) ; 7 23 0011 2600 ld h,0 ; 7 23 0013 23 inc hl ; 6 23 0014 23 inc hl ; 6 23 0015 d1 pop de ; 10 23 0016 7d ld a,l ; 4 23 0017 12 ld (de),a ; 7 23 0018 c1 pop bc ; 10 23 0019 c9 ret ; 10
-
コンパイル
compile.sh
#!/bin/sh
zcc +msx -lmsxbios --list -subtype=msxdos $1.c -o $1.com
$ ./compile.sh ./func1
実行結果

※MSXDOS.SYSとCOMMAND.COM、コンパイルして作成した.COMを配置したディレクトリをopenMSXでマウント、MSXDOSから実行