You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何理解指针(*)与取地址(&)运算符?C语言函数传参疑问咨询

关于C语言指针、取地址运算符与传值/传引用的疑问解答

一、为什么analyse_inst的参数必须是char*?

你写的原代码里,mnemonic和operands都是char*类型——它们本质是指向字符串首字符的指针,存储的是字符串第一个字符在内存中的地址。

如果你的函数参数写成char mnemonic,这意味着你要把mnemonic指针指向的第一个字符(也就是字符串"add"里的'a')复制一份传给函数形参。但printf("%s", ...)要求传入的是字符串的首地址(char*类型),你传单个char进去,编译器会把这个字符的ASCII值当成内存地址来访问,这显然是非法的(会触发未定义行为,程序崩溃或者乱输出)。

而当你把参数改成char* mnemonic时,你传递的是指针本身的值(也就是字符串的首地址),函数形参拿到这个地址后,printf就能从这个地址开始,逐个打印字符直到遇到字符串结束符\0,这才是正确的用法。

二、关于传值和传引用的理解,你是对的,但要注意C语言的特殊性

你的理解基本没问题:

  • 传值:把实参的副本传给形参,函数里修改形参不会影响到函数外的实参——因为两者是完全独立的变量,只是值相同。
  • 传引用:把实参的地址传给形参,函数通过这个地址直接访问/修改实参所在的内存,所以修改会影响到函数外的变量。

但要注意:C语言本身并没有原生的“传引用”语法,我们平时说的C语言传引用,其实是通过传递指针的方式模拟实现的。而且哪怕传递指针,本质上还是传值——因为我们传递的是指针的副本(也就是地址值),只不过这个副本和原指针指向同一块内存,所以修改这块内存的内容会影响外部;但如果你在函数里修改指针本身(比如让形参指针指向另一个地址),外部的原指针不会变,因为形参是独立的副本。

三、修改你的代码实现“传引用”(模拟)

原代码里的mnemonic和operands指向的是常量字符串(存储在只读内存区),不能直接修改内容。所以我们可以做两个方向的修改:

1. 修改字符串的内容(需要用字符数组,而不是指向常量字符串的指针)

如果想在函数里修改字符串的内容,需要把变量改成字符数组(因为字符数组存在栈上,可修改),然后函数参数用char*(传递数组首地址,本质是传指针值,模拟传引用):

#include <stdio.h>
#include <string.h>

void analyse_inst(char *mnemonic, char *operands) {
    // 修改mnemonic的内容
    strcpy(mnemonic, "sub");
    // 修改operands的内容
    strcpy(operands, "three from ten");
}

int main() {
    // 用字符数组存储字符串,而不是指向常量字符串的指针
    char mnemonic[10] = "add";
    char operands[20] = "five to two";
    
    analyse_inst(mnemonic, operands);
    // 打印修改后的结果
    printf("修改后的mnemonic: %s\n", mnemonic);
    printf("修改后的operands: %s\n", operands);
    return 0;
}

这里传递的是字符数组的首地址,函数里通过这个地址修改数组内容,外部的mnemonic和operands数组会跟着变化——这就是模拟的传引用。

2. 修改指针的指向(需要用指向指针的指针char**)

如果想在函数里让原指针指向新的字符串,就需要传递指针的地址(也就是char**类型),这样函数里修改的是原指针本身的内容:

#include <stdio.h>
#include <string.h>

void analyse_inst(char **mnemonic, char **operands) {
    // 让原指针指向新的常量字符串
    *mnemonic = "mul";
    *operands = "four times six";
}

int main() {
    char *mnemonic = "add";
    char *operands = "five to two";
    
    analyse_inst(&mnemonic, &operands);
    // 打印修改后的指针指向的内容
    printf("修改后的mnemonic: %s\n", mnemonic);
    printf("修改后的operands: %s\n", operands);
    return 0;
}

这里我们用&mnemonic取到指针变量本身的地址,传给函数的char**形参,函数里通过*mnemonic修改原指针的指向,这样外部的mnemonic和operands指针就会指向新的字符串。


内容的提问来源于stack exchange,提问作者Tina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:04:23