参数传递方式

参数传递方式教材上大都说有两种,一种是值传递,另一种是指针传递。而后者本质上依然是值传递。

底层原理

对于值传递还是指针传递,传递的都是相应的值,只不过指针传递传递的是地址的副本,修改副本对原来数据没有任何影响,需要修改的是地址的指向。关于函数调用的执行流程可参考strcpy为何不安全

bool test(int* x) {
    int b = 10;
    //memcpy(a, &b, sizeof(int));
    x = &b;
    //*a = b;
    return true;
}

int main()
{
   // std::cout << "Hello World!\n";
    std::string filename = "11.png";
   // FILE* fp = fopen(filename.c_str(), "rb");
    char* s = new char[20];
    int a = 0;
    int * p = &a;
    test(p);
    std::cout << a;
}

此时的运行结果是0
而将代码修改为

bool test(int* x) {
    int b = 10;
    //memcpy(a, &b, sizeof(int));
    //x = &b;
    *x = b;
    return true;
}

此时的运行结果是10,也就是修改后的内容。
两段代码的区别:第一段代码 x = &b;对应的汇编代码是,修改的是x的值得,对原本的数据a没有任何影响。

00B62F26  lea         eax,[b]    //将b所指向的内存地址(而不是b的值)加载到eax寄存器中
00B62F29  mov         dword ptr [x],eax  //将 eax 寄存器中的32位(双字)值存储到 x 所指向的内存地址中

而*x = b;对应的汇编代码是,修改可地址的指向。

00492F1C  mov         eax,dword ptr [x]   //将x的值赋值给eax,x的值是a对应的地址
00492F1F  mov         ecx,dword ptr [b]  //将b内存中的值复制给ecx
00492F22  mov         dword ptr [eax],ecx  //将ecx的值赋值给eax指向的内存中的值

char *传值问题

bool test(int* x, char * str) {
    char* p = new char[200];
    memset(p, 0, 200);
    p[0] = 'H';
    p[1] = 'E';
    p[2]  = 'l';
    p[3] = '\0';
    int len = strlen(p);
    strcpy_s(str, strlen(p)+1, p);
    delete(p);
    return true;
}

不能使用str = p;这种只是修改副本的值,对原来的char*没有任何影响。

list传值问题

c++中list传递需要使用指针或者引用,才能改变原本的值。

bool test_list(list<string> *testList) {
    testList->push_back("3");
    return false;
}

调用方:

List<String> li;
li.push_back("1");
li.push_back("2");
test_list(&li);

或者

list<string> *li =  new std::list<string>();
li->push_back("1");
li->push_back("2");
test_list(li);

这两个语句都是用于创建一个存储字符串的列表。主要的区别在于:

  1. 数据类型的差异:前者使用的是C++标准库中的list容器,后者是使用指针创建的动态内存。

  2. 声明方式的差异:前者是一般的对象声明方式,后者是通过new运算符动态地分配内存并返回一个指向该内存区域的指针。

  3. 内存管理的差异:前者是一个自动管理内存的对象,当程序执行到其作用域结束或者该对象被销毁时,内存会自动释放;后者需要手动使用delete运算符释放动态分配的内存。

因此,建议在使用时考虑到实际情况,选择合适的声明方式和内存管理方式。如果只是需要临时存储字符串,并且不想手动管理内存,可以选择前者;如果需要在程序运行期间动态地分配和释放内存,并且需要手动管理内存,可以选择后者。

c#中的list传递,不需要指针或者引用。像java之类的语言类似,这也是java等语言比c相对简单的原因。

List<String> li = new List<String>();
li.Add("1");
li.Add("2");
await test(li);
Console.WriteLine(li);
Task test(List<String> list_test)
{
    list_test.Add("3");
    return Task.CompletedTask;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

helloworddm

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值