指针混乱:c 中的交换方法

2024-05-14

#include<stdio.h>
void swap(int *a,int *b){
    int p=*b;
    *b=*a;
    *a=p;

    /*int *p=b;
    b=a;
    a=p;
    */
}

int main(){
    int a,b;
    scanf("%d %d",&a,&b);
    swap(&a,&b);
    printf("%d %d",a,b);
}

以上是代码。

如果我将 3 5 作为输入,那么它应该交换其值,并且 5 3 应该作为输出出现。 我通过尝试 int p=*b 得到了答案

不过我也尝试过评论部分,但没有成功。

所以,我检查了它们在交换和主地址中的地址。

在交换 int *a 和 int *b 中,它们的地址发生了变化

然而,当我回到 main 时, a 和 b 的地址没有改变......

所以首先我想:是不是因为参数 int *a,int *b 是局部变量,所以 main 中没有改变?

但我还了解到,当指针和参数用作参数时,它们的值可以像其他变量一样改变......

我真的想知道为什么第二种方法(注释部分)不交换值......


如果您想更改函数中的原始对象,则必须通过引用将它们传递给函数。

在 C 中,通过引用传递对象意味着通过指向原始对象的指针间接传递它们。

否则,如果您将原始对象本身传递给函数,该函数将处理对象的副本。显然,更改副本不会影响原始对象。

这正是这个函数中发生的事情

void swap(int *a,int *b){
    int *p=b;
    b=a;
    a=p;
}

该函数处理作为此调用中的参数传递给函数的指针的副本

swap(&a,&b);

也就是说,该函数确实交换了声明为其参数的两个指针的值。但它们不是传递给函数的原始指针。它们是指针的副本。所以原来的指针的值没有改变

函数交换一般可以如下所示

void swap( T *a, T *b )
{
    T tmp = *a;
    *a = *b;
    *b = tmp;
}  

where T是相同的类型说明符。

所以如果你想交换该类型的对象int然后在上面的函数中Tint该函数看起来像

void swap( int *a, int *b )
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}  

如果你想交换类型指针的值int * then Tint *该函数看起来像

void swap( int **a, int **b )
{
    int *tmp = *a;
    *a = *b;
    *b = tmp;
}  

这是一个演示程序。

#include <stdio.h>

void swap1( int *pa, int *pb )
{
    int tmp = *pa;
    *pa = *pb;
    *pb = tmp;
}

void swap2( int **ppa, int **ppb )
{
    int *tmp = *ppa;
    *ppa = *ppb;
    *ppb = tmp;
}

int main(void) 
{
    int a = 3, b = 5;

    swap1( &a, &b );

    printf( "a = %d b = %d\n", a, b );

    //  reset again the values of the variables
    a = 3; b = 5;

    int *pa = &a, *pb = &b;

    swap2( &pa, &pb );

    printf( "*pa = %d *pb = %d\n", *pa, *pb );

    return 0;
}

它的输出是

a = 5 b = 3
*pa = 5 *pb = 3

首先在程序中存在两个类型的对象int被交换,所以想象的类型说明符T is int.

然后是两个指向对象的指针a and b被交换。所以想象的类型说明符T int *.

交换指针后pa现在指向该对象b和指针pb现在指向该对象a.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

指针混乱:c 中的交换方法 的相关文章

  • 扫描文本文件时如何跳过行?

    我想扫描一个文件并在阅读之前跳过一行文本 我试过 fscanf pointer n struct test i j 但这个语法只是从第一行开始 我可以使用 scanf 使用以下指令跳过行 fscanf config file n n 格式字
  • 更快的算法来计算有多少数字可以被范围内的特定整数整除

    int a b c d 0 cin gt gt a gt gt b gt gt c for int i a i lt b i if i c 0 d cout lt
  • C修改printf()输出到文件

    有没有办法修改printf为了将字符串输出到文件而不是控制台 我尝试在互联网上查找一些内容 发现了类似的电话dup dup2 and fflush这可能与此有关 EDIT 也许我不清楚 问题是这是C考试问题 问题如下 解释一个通常将字符串输
  • 检查列表是否包含另一个列表。 C#

    编辑 只是说 ContainsAllItem 中的注释解释得最好 很抱歉问这个问题 我知道以前有人问过这个问题 但我只是不明白 好的 所以我想检查一个列表是否包含另一个列表中的所有项目WITHOUT重叠 以及根据类字符串 名称变量 称为项目
  • 切换图片框可见性 C#

    为什么图片框控件的可见性属性在这里不起作用 我最初将它们设置为 false 以便在屏幕加载时它们不可见 但后来我想切换这个 我已完成以下操作 但似乎不起作用 这是一个 Windows 窗体应用程序 private void Action w
  • WebClient读取错误页面的内容

    我有一个加载页面内容的应用程序 我使用 WebClient 类 即使服务器返回 404 500 等错误 我也需要检索内容 我需要这样的东西 WebClient wc new WebClient string pageContent try
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 如何将字节块读入结构体

    我有一个需要处理的资源文件 它包含一组文件 首先 资源文件列出了其中包含的所有文件 以及一些其他数据 例如在此结构中 struct FileEntry byte Value1 char Filename 12 byte Value2 byt
  • 将成员函数作为参数传递/c++

    我想用 C 实现一个类b可以通过封装该迭代器类型的成员集进行某种迭代 喜欢 b object for each x do function f so 函数 f会得到每个人的x成员并做任何事情 比方说 void function f x me
  • 用 C# 制作 Vista 风格的应用程序

    我正在运行 Windows Vista 并且希望外观看起来像常规 Vista 程序 有没有关于如何构建 Vista 风格应用程序的真正好的教程 文章 我还想学习如何使用本机代码并将其转换为 C 如this http bartdesmet n
  • 使用 openssl 检查服务器安全协议

    我有一个框架应用程序 它根据使用方式连接到不同的服务器 对于 https 连接 使用 openssl 我的问题是 我需要知道我连接的服务器是否使用 SSL 还是 TLS 以便我可以创建正确的 SSL 上下文 目前 如果我使用错误的上下文尝试
  • 导出到 CSV 时 Gridview 出现空行

    这个问题是由进一步讨论引发的这个问题 https stackoverflow com questions 6674555 export gridview data into csv file 6674589 noredirect 1 com
  • C# 中处理 SQL 死锁的模式?

    我正在用 C 编写一个访问 SQL Server 2005 数据库的应用程序 该应用程序是数据库密集型的 即使我尝试优化所有访问 设置适当的索引等 我预计迟早会遇到死锁 我知道为什么会发生数据库死锁 但我怀疑我能否在某个时候发布不发生死锁的
  • 如何不在类中实现接口的功能?

    面试时面试官问了我以下问题 但我不知道这个问题的答案是什么 请帮忙 如果我不想 我必须做什么 在我的类中实现一个函数 在接口中声明为 由我班实施 Edited 我正在使用 NET 和 C 如果有人可以提供 C 示例代码示例 那就太好了 Th
  • Dynamics Crm:获取状态代码/状态代码映射的元数据

    在 Dynamics CRM 2011 中 在事件实体上 状态原因 选项集 也称为状态代码 与 状态 选项集 也称为状态代码 相关 例如看这个截图 当我使用 API 检索状态原因选项集时 如下所示 RetrieveAttributeRequ
  • C++ 标准中短语“构造函数没有名称”的含义

    在尝试理解 C 标准中的 构造函数没有名称 这句话时 我似乎在 clang 中发现了一个错误 有人可以证实这一点吗 VS2015 and gcc rejects this code and I think they it are is co
  • 为什么 C# 接口名称前面加上“I”

    这种命名约定背后的基本原理是什么 我没有看到任何好处 额外的前缀只会污染 API 我的想法与康拉德一致response https stackoverflow com a 222502 9898与此相关的question https sta
  • 如何强制执行特定的 UserControl 设计

    我正在编写一个基本用户控件 它将由一堆其他用户控件继承 我需要对所有这些后代控件强制执行某种设计 例如 顶部必须有几个按钮以及一个或两个标签 后代用户控件区域的其余部分可以自由放置任何内容 最初 我认为我可以将一个面板放到 Base Use
  • 将文本从文本文件添加到 PDF 文件[重复]

    这个问题在这里已经有答案了 这是我的代码 using FileStream msReport new FileStream pdfPath FileMode Create step 1 using Document pdfDoc new D
  • 如何从函数返回矩阵(二维数组)? (C)

    我创建了一个生成宾果板的函数 我想返回宾果板 正如我没想到的那样 它不起作用 这是函数 int generateBoard int board N M i j fillNum Boolean exists True initilize se

随机推荐