指针大小和按引用传递与按指针传递
Pointer size and Pass-by-Reference vs. Pass-by-Pointer
>我有两个问题:
-
我说得对吗,在 4 位系统上,指针是 4 个字节?
"通过引用传递" 和"通过指针传递"是一回事,只是措辞不同吗?
我是否正确,在 4 位系统上指针大小为 4
如果您的系统有 1 位字节,那么肯定是。(但 C 不支持字节短于 8 位的平台。
"通过引用"和"通过指针传递"是一回事,但措辞不同吗?
不。按指针传递是一种用于模拟按引用传递的 C 方法。概念是不同的。
指针的大小不一定与CPU的本机字大小相关;例如,最初的Macintosh运行在32位处理器(摩托罗拉68000)上,该处理器只有24个地址行,因此指针被限制为24位。 指针值存储在 32 位字中,但未使用前 8 位。 一些有进取心的程序员使用前 8 位来存储带有指针的其他数据。 当68020问世时,这引起了一些胃灼热,它有32个地址行。 重写该代码需要一段时间,使其"32位干净"。
另请注意,指向不同类型的指针不必具有相同的大小。
实际上,在任何现代桌面系统(读取:x86)上,所有指针类型都将是 32 位或 64 位宽。 但不要依赖所有架构都是如此。
至于"通过引用传递"和"通过指针传递",不,它们不仅仅是同一概念的不同措辞。
在按引用传递系统中,函数定义中的形式参数和函数调用中的实际参数指定相同的内存(或者至少对一个内存的更改反映在另一个内存中)。 查看一些老式的Fortran代码:
C234567890
PROGRAM CALLSW
INTEGER M, N
M = 1
N = 2
WRITE(*,*) M, N
CALL ISWAP(M, N)
WRITE(*,*) M, N
STOP
END
C234567890
SUBROUTINE ISWAP(A, B)
INTEGER A, B
INTEGER TMP
TMP = A
A = B
B = TMP
RETURN
END
ISWAP
中的形式参数 A
指定内存中与主程序中M
相同的对象,因此写入 A
会更改 M
中的值。 您可以将A
视为指向M
的指针(或者A
和M
都是指向同一对象的指针),但该语言对程序员隐藏了该指针性。
C 按值传递所有内容;形式参数和实际参数总是指定内存中的不同对象,因此写入一个不会影响另一个对象。 当我们要修改子例程中的对象时,我们必须使用 &
运算符显式传递其地址,然后在子例程中使用 *
运算符取消引用它:
void iswap(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
int main(void)
{
int m, n;
m = 1;
n = 2;
printf("m = %d, n = %dn", m, n);
iswap(&x, &y);
printf("m = %d, n = %dn", m, n);
return 0;
}
我们不是将m
和n
传递给iswap
,而是传递表达式&m
和&n
的结果,它们是指向两个对象的指针。 同样,在iswap
函数中,我们不写入a
或b
,而是写入表达式*a
和*b
的结果。 a
和m
指的是内存中两个完全不同的对象,b
和n
也是如此。 写信给a
根本不会影响m
。
中的参数传递,维基百科关于 C 的条目指出:
函数参数始终按值传递。通过显式传递指针值在 C 中模拟按引用传递。
- 将函数参数完美转发到函数指针:按值传递呢?
- 按值传递变量与按引用传递变量具有相同的结果
- 获取 std::函数以推断按引用传递/按值传递
- C++/11 auto 关键字是在更有效时推导参数进行按引用传递,还是始终按值传递?
- 使用 enable_if 在按值传递与按引用传递之间更改函数声明
- 按引用传递和按地址传递之间的差异
- C++按引用传递还是按值传递?
- 可移动但不可复制的对象:按值传递还是按引用传递?
- 使用增量运算符按引用传递
- C++函数,按引用传递
- 按引用传递和动态内存分配之间的区别是什么
- 通过查看程序集来比较按值传递与按引用传递性能
- 在形式参数列表中自动使用 const 和按引用传递的任何明显后果
- 按引用传递函数参数
- 为什么在按值传递指针之后再按引用传递指针会指向原始内存位置
- 使用按引用传递而不是按指针传递时的二进制兼容性
- 当“按引用传递”成为强制传递而不是按地址/指针传递时
- C++ 按引用传递,而不是按值/指针传递
- 指针大小和按引用传递与按指针传递
- 使用指针和解引用指针按引用传递