关于#c语言#的问题:6但是在sp函数最后为a所赋值为4,但结果却是6是否是因为b是函数内的变量


#include <stdio.h>

void sp(int* a) {
    int b = 2;
    *a = *a * 2;
    printf("%d, ", *a);
    a = &b;
    *a = *a * 2;
    printf("%d, ", *a);
}

int main() {
    int k = 3;
    sp(&k);
    printf("%d\n", k);
}

代码运行结果为6,4,6
但是在sp函数最后为a所赋值为4,但结果却是6
是否是因为b是函数内的变量,在出来函数后,撤销a的值,返回上一个值

"b是函数内的变量,在出来函数后,撤销a的值,返回上一个值"
不是
a = &b; 这是关键
这个之后操作的就和主程序k没关系了,因为指向了局部变量b

k是main函数中的变量,sp(&k)把k的地址传输过去之后,a变量赋值了k的地址,*a = a * 2这条语句让k的值变成了6,a = *a * 2;这条语句修改了a变量中存储的地址,所以后面的操作不会影响到k的值了。所以最后你打印出来k的值就是6

参数a是一个地址的拷贝,指向k的地址,执行完第一个 *a = a * 2;之后k的值变为6;当a = &b;后,a指向b的地址,第二次执行a = *a * 2;此时k的值并未被改变,因此最后的结果是6,并是因为b是函数内的变量,是因为指针a指向的地址变了,并不是指向k的地址。

因为函数sp(int *a) 形参为指针,在主函数里调用sp(&k)时,指向了变量k,所以在sp()函数里对 *a = *a * 2 的操作等价于 k = k * 2 = 3 *2 = 6,这句执行完输出第一个 6。a = &b ; 这句让指针形参a 指向了变量 b ,所以再执行 *a = *a * 2 时,等价于 b = b * 2 = 2 * 2 = 4,这句执行完输出第二个数 4。
回到主函数里,此时主函数里 k 的值已被在sp()函数里对 *a = *a * 2 的操作等价于 k = k * 2 = 3 *2 = 6 所改变,所以输出第三个数 6。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7549470
  • 你也可以参考下这篇文章:不用临时变量交换a,b值的三种方法
  • 除此之外, 这篇博客: 用指向一维数组a的指针变量实现对二维数组b中各元素的输入和输出中的 用指向一维数组a的指针变量实现对二维数组b中各元素的输入和输出 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    编写程序,用指向一维数组的指针变量p实现对二维数组b中各元素的输入和输出。要求:输出用指针变量的多种表现形式进行数组元素的多次输出。

    完蛋 写的时候没发现…现在总感觉我题意理解错了emmmm’
    应该没有8哈哈哈
    把所有能想到的书上能看到的指针变量的表现形式都写了
    奶思!!

    #include <stdio.h>
    
    int main(int argc, char const *argv[]) {
      int b[2][3];
      int (*p)[3] = b;
      for (int i = 0; i < 6; i++) {
      scanf("%d", &p[0][i]);
      }
      for (int i = 0; i < 6; i++) {
        printf("%d ", (*p)[i]);
      }
      printf("\n");
      for (int i = 0; i < 6; i++) {
        printf("%d ", *((*p)+i));
      }
      printf("\n");
      for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
          printf("%d ", p[i][j]);
        }
      }
      printf("\n");
      for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
          printf("%d ", (*(p + i))[j]);
        }
      }
      printf("\n");
      for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
          printf("%d ", *(p[i] + j));
        }
      }
      printf("\n");
      return 0;
    }
    
    

    陕西科技大学 C语言程序设计课作业 指针-20190327 第五题

  • 以下回答来自chatgpt:

    函数内部变量的作用范围导致结果不符合预期的原因是,函数内部变量是局部变量,它的作用范围仅限于函数内部。当函数执行完毕后,局部变量会被销毁,内存空间会被释放。但是在某些情况下,函数内部的局部变量可能会影响到函数外部的变量,原因如下:

    1. 函数内部变量和函数外部变量具有相同的名称:如果函数内部变量和函数外部变量具有相同的名称,在函数内部使用该变量时,会优先使用函数内部的局部变量。这样就会导致函数外部的变量无法被访问到或者被修改了。

    2. 引用传递:C语言中的函数参数传递方式有值传递和引用传递两种。如果函数参数采用的是引用传递方式,在函数内部对参数进行修改时,实际上是修改了参数所指向的内存空间,而不是创建了一个新的局部变量。这样就会影响到函数外部的变量。

    对于你提到的问题,函数内部变量的改变影响了函数外部变量的值,可能是因为函数内部的变量与函数外部的变量具有相同的名称,并且它们的地址相同。这导致在函数内部修改变量的值时,实际上修改的是函数外部的变量值。

    为了解决这个问题,可以通过以下方式进行操作:

    1. 修改函数参数名或局部变量名:如果函数内部的变量名称与函数外部的变量名称相同,可以修改函数内部的变量名称,避免命名冲突。

    2. 使用指针传递:通过传递指针作为函数参数,可以在函数内部通过解引用操作修改指向的内存空间的值,从而同时改变函数外部的变量值。

    示例代码:

    #include <stdio.h>
    
    void changeValue(int* a) {
        *a = 4; // 修改指针所指向的内存空间的值
    }
    
    int main() {
        int a = 6;
        printf("Before change: %d\n", a); // 输出结果为6
    
        changeValue(&a); // 传递变量a的地址给函数进行修改
    
        printf("After change: %d\n", a); // 输出结果为4
    
        return 0;
    }
    

    通过将变量a的地址传递给函数changeValue,在函数内部通过指针解引用操作修改变量a的值,实现了对函数外部变量的修改。

    希望以上解答能够帮助到您!如有疑问,请及时追问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^