草庐IT

C语言-值传递、地址传递与引用

两分钱 2023-03-28 原文

1、引例

【例1】 分析该程序,有哪些问题

int main()
{
    swap(int p, int q);
    int a = 10, b = 20;
    printf("(1)a = %d, b = %d\n", a, b);
    swap(&a, &b);
    printf("(2)a = %d, b = %d\n", a, b);
}
swap(int p, int q)
{
    int t;
    t = p;
    p = q;
    q = t;
}
分析,该程序的功能是将a和b的值通过函数swap()进行交换,最后输出结果,但编译时会发生语法错误。
修改意见:
1、定义、声明用户自定义函数时,因该对函数添加返回值(即将第9行和第3行修改为void swap(int p, 、int q))。
2、由于定义函数swap()时,参数p和q 都为整型,因此当调用该函数时,实际参数也应为整型(即,将第6行改为 swap(a, b)
修改后,该程序为
int main()
{
    void swap(int p, int q);
    int a = 10, b = 20;
    printf("(1)a = %d, b = %d\n", a, b);
    swap(a, b);
    printf("(2)a = %d, b = %d\n", a, b);
}
void swap( int p,  int q)
{
    int t;
    t = p;
    p = q;
    q = t;
}
程序的运行结果为:
可见,虽然程序可以运行,但并没有实现对a和b 的值交换。
 

2、值传递

2.1 定义

定义 1 (值传递)在调用函数的过程中,只将实参的值赋值(复制)给形参,被调用函数的内部对形参的修改,不会引起实参的变化。

【例2】值传递

int main()
{
    void swap(int p, int q);
    int a = 10, b = 20;
    printf("(1)a = %d, b = %d\n", a, b);
    swap(a, b);
    printf("(2)a = %d, b = %d\n", a, b);
}
void swap( int p,  int q)
{
    int t;
    t = p;
    p = q;
    q = t;
}

这种方式叫做值传递。在main函数执行过程中,当执行到调用函数swap(a,b)时,此时main函数跳转到swap函数继续执行,同时将实参a和b的值赋值(复制)给形参p和q,在swap函数内部借助变量t,实现形参p和q值的交换(然而形参p和q值的交换,对实参a和b的值并无影响,该语句只是将实参a和b的值赋值给形参p和q,仅此而已)。当调用函数执行完之后,返回到调用函数swap(a,b)的下一条语句继续执行。

3、地址传递

3.1 定义

定义 2(指针传递)在调用函数的过程中,将实参的地址传递给形参,被调用函数的内部对形参的修改,会同步引起实参的修改。

【例3】地址传递

int main()
{
    void swap(int *p, int *q);
    int a = 10, b = 20;
    printf("(1)a = %d, b = %d\n", a, b);
    swap(&a, &b);
    printf("(2)a = %d, b = %d\n", a, b);
}
void swap( int *p,  int *q)
{
    int t;
     t = *p;
    *p = *q;
    *q = t;
}

这种方式叫做指针传递。在执行调用函数的过程中,调用函数swap(&a,&b)将实参a、b的地址赋值给形参p、q,由于p、q为指针,那么p、q所指向的值与a、b的值必然相同(即p、q分别指向a、b)。在调用函数内部,对p、q所指向的值修改,即是对实参a、b值的修改。

4、引用

4.1 定义

定义 3(引用)对某一变量的重命名(别名),对引用的操作等同于对变量的操作。

4.2 声明

类型标识符 &引用名=目标变量名

【例4】

int b;

int &a=b;  // 定义了引用a,即a是变量b 的别名

注:

(1)& 为标识符,不是取地址运算

(2)声明引用的同时,必须同时初始化

(3)当对目标变量声明引用之后,等同于目标变量有一个别名,即 a=1等价于b=1

(4)引用不占存储单元,对引用求地址,等同于对目标变量求地址,即  &a=&b

(5)对数组不能建立引用

4.3 用途

(1)函数参数传递,

用引用传递参数,由于引用不占用内存空间,对引用的修改即是对目标函数的修改,从而提高效率

4.4 与指针的区别

指针是通过指针变量对所指向的值间接操作,使用指针,程序的可理解性变差。而引用时目标变量的别名,对引用的操作就是对目标变量的操作。

【例5】引用传递参数

int main()
{
    void swap(int &p, int &q);
    int a = 10, b = 20;
    printf("(1)a = %d, b = %d\n", a, b);
    swap(a, b);
    printf("(2)a = %d, b = %d\n", a, b);
}
void swap( int &p,  int &q)
{
    int t;
    t = p;
    p = q;
    q = t;
}

运行结果

 

 

有关C语言-值传递、地址传递与引用的更多相关文章

  1. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  2. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  3. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  4. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

  5. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  6. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  7. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  8. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  9. 7个大一C语言必学的程序 / C语言经典代码大全 - 2

    嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来

  10. ruby - 如何将 Puma::Configuration 传递给 Sinatra? - 2

    这是我的网络应用:classFront我是这样开始的(请不要建议使用Rack):Front.start!这是我的Puma配置对象,我不知道如何传递给它:require'puma/configuration'Puma::Configuration.new({log_requests:true,debug:true})说真的,怎么样? 最佳答案 配置与您运行的方式紧密相关puma服务器。运行的标准方式puma-pumaCLI命令。为了配置puma配置文件config/puma.rb或config/puma/.rb应该提供(参见examp

随机推荐