基于指针传递(Call by Reference)的数值循环移位函数逻辑解析
C语言传引用调用实现循环移位:shift函数与地址传递解析
一、shift函数的具体含义
先看一段典型的循环移位实现代码:
#include <stdio.h> void shift(int *num, int n) { // 获取int类型的总位数(通常为32位) int bits = sizeof(int) * 8; // 处理移位位数超过总位数的情况,避免无效操作 n %= bits; // 把负移位(循环右移)转换为等效的正移位(循环左移) if (n < 0) n += bits; // 执行循环左移:左移n位后,将溢出的高位补到低位 *num = (*num << n) | (*num >> (bits - n)); } int main() { int val = 0x12345678; // 传入val的内存地址,实现传引用效果 shift(&val, 4); printf("移位后的值:0x%X\n", val); return 0; }
这个shift函数的核心作用是对目标整数执行循环移位操作:
- 第一个参数
int *num是指向目标整数的指针,用来直接操作原变量的内存 - 第二个参数
n是移位位数:正数表示循环左移,负数表示循环右移 - 函数内先将移位位数调整到有效范围(0到总位数-1),再通过位运算完成循环移位——左移n位后,把溢出的高位通过右移
bits-n位提取出来,和左移后的值做按位或,得到最终的循环移位结果
二、地址传递的逻辑
C语言没有原生的“传引用”机制,所谓的传引用调用是通过指针传递地址模拟的,整个过程的地址传递逻辑如下:
- 在
main函数中,&val取出变量val的内存地址(比如0x7ffeefbff5ac) - 调用
shift(&val, 4)时,该地址被赋值给函数参数int *num——此时num存储的就是val的地址,相当于num直接指向了val的内存空间 - 在
shift函数内部,*num是对指针的解引用操作,直接访问num指向的内存(也就是val的内存),所以对*num的赋值会直接修改val的原始值,而非传值调用中修改的副本 - 函数执行完毕后,
num作为局部变量被销毁,但val内存地址上的值已经被修改,main函数中可以直接拿到移位后的结果
三、传值与传引用的核心区别
- 传值调用:函数接收的是变量的副本,修改副本不会影响原变量
- 指针模拟的传引用:函数接收的是变量的地址,通过地址直接操作原变量的内存,修改会直接作用于原变量
内容的提问来源于stack exchange,提问作者Harshal Malani
相关产品推荐
相关产品推荐

