关于【指针作为形参,改变实参的值】的理解!

0x01

  先上代码:

 1 #include <stdio.h>
 2
 3 void swap(int *p, int *q)
 4 {
 5     int temp;
 6     temp = *p;
 7     *p = *q;
 8     *q = temp;
 9 }
10
11 int main()
12 {
13     int a, b;
14     int *pa, *pb;
15     printf("Enter 2 numbers:\n");
16     scanf("%d, %d", &a, &b);
17     pa = &a;
18     pb = &b;
19
20     printf("a = %d, b = %d\n", a, b);
21     printf("=====Changed======\n");
22     swap(pa, pb);
23     printf("a = %d, b = %d\n", a, b);
24 }

  代码的作用:通过指针交换两个变量的值。

  运行结果:

  

0x02

  指针是如何交换两个变量的值的?

  首先需要明白下面的东西:

  (1)星号"*"的两个作用:①定义指针变量  ②指明指针所指变量的值(间接访问)

  (2)指针变量作为函数参数,是将变量的地址传递给函数;

  分析:swap()函数的参数是指针变量,所以接收的是变量的地址,【(这段话是在网上看到的)指针传递的是变量的地址,也就是它在内存中的所在位置,它发生改变,变量就改变;一般变量做形参,传递的是变量的值,地址不发生改变,函数在执行过程中调用内存空间,执行完便释放内存空间,所以不改变。】

  在交换变量值的代码中,重要的是(*p = *q, *q = temp),这句代码的作用是,将指针q指向的内容赋给指针p所指的区域。

  自己的理解:*p = *q; *p指的是指针变量p(*号的作用是定义指针变量),*q指的是间接访问q所指区域中的值(*号的作用是间接访问),将这个值赋予p所指的区域,也就是【地址】,这个地址是传入的a的地址,所以a的地址(或者说a对应的内存空间)中存放的内容就改变了,成了q的所指区域中的值,也就是b的值,这样就完成了交换。重要的还是要分清星号*的两个作用。 ====但是还有疑问,值能直接赋给地址?或者说星号*在等号左右两边的意义不同,在左边表示变量,右边表示间接访问?====

  temp = *p;  temp是一个整型变量,*p是间接访问指针所指区域的内容,也就是a的值,所以这句代码的作用就是将a的值赋值给temp;

  *q = temp; temp之前被赋予a的值,*q指的是指针变量q(*号的作用是定义指针变量),值是b的地址,将a的值放在b的地址中,所以b对应的内存空间中的内容成了a的值。

0x03

  下面代码也是同样的道理:

 1 #include <stdio.h>
 2 int main()
 3 {
 4     int a, *p;
 5     int b = 10;
 6     printf("Enter a number:\n");
 7     scanf("%d", &a);
 8     p = &a;
 9     printf("a = %d\n", a);
10     printf("*p = %d\n", *p);
11
12     printf("\n=============\n");
13     *p = b;
14     printf("a = %d\n", a);
15     printf("*p = %d\n", *p);
16 }

  首先指针p指向变量a,然后通过*p = b; 改变了a的值;

  运行结果:

  

  

0x04

  其实不只是指针作为形参改变实参,而是指针就具有这个“特性”。

  

时间: 2024-10-20 04:44:39

关于【指针作为形参,改变实参的值】的理解!的相关文章

c#中数组名作为参数如何通过修改形参的值来改变实参的值?

using System; namespace ConsoleApplication1 { class Program { void f(int[] a) { a[0] = 1;//通过这种方式就可以修改实参的值,说明通过这种方式就是在原内存上来修改元素的值 } static void Main(string[] args) {Program obj=new Program(); int[] a =new int[4] { 6, 7, 8, 9 }; obj.f(a); for (int i =

//形参改变实参

//形参改变实参 #include<stdio.h> void change(int *n); int main(){ int a = 90; change(&a); printf("%d\n",a); return 0; } void change(int *n){ *n = 10; }

C#形参,实参,值传递参数,引用传递参数,输出参数,参数数组的学习

1)形参 形参顾名思义就是形式上的参数,不是实际的参数,它代替实际传入方法的值.在方法体代码中代表了值本身参与运算.形参定义于参数中,它不同于方法体内局部变量,因为是一个变量,在它的作用域内不允许存在一个同名的局部变量,不管他们的类型是否相同,都是不允许出现同名的. 看下面的代码示例: 1 //这其中的strName就是一个形参也是一个变量,不允许出现同名的局部变量 2 public void SayHelloTo(string strName) 3 { 4 Console.WriteLine(

把指针作为形参,用于取值的用法。

指针作为函数的形参有两种用法:1.传值.2.取值.下面我们讨论下,使用指针取值的用法.指针之所以能够用来取值是作用域和生存周期的原因. (1)用一级指针取数值. int fun1(int* p) { *p = 3;// *p为整型变量,3为整数常量.如此两侧对等. } (2)用二级指针取一级地址值. int fun2(int** p) { int* pnew = (int*)malloc(sizeof(int)); *p = pnew;// *p是一级指针变量,pnew也是一级指针变量.如此两侧

通过指针形参修改实参的值2

注意:图示使用的地址只是假设的,并不是真正的内存地址,只是说明原理 上次说到的是修改基本类型的变量,这次来说修改指针变量的值 #include <stdio.h> void change(int *a) { int temp = 555; a = &temp; } int main() { int i = 5; int *p = &i; printf("%p\n", p); change(p);//并没有修改成功p的值 printf("%p\n&q

通过指针形参修改实参的值1

注意:图示使用的地址只是假设的,并不是真正的内存地址,只是说明原理 先说说修改基本类型变量的值,比如说int类型,可以直接修改,也可以通过函数修改,看下代码 #include <stdio.h> void change(int *a) { int temp = 555; a = &temp; } int main() { int i = 5; int j = 55; int *p = &i; i = 10;//第一种修改方法 printf("%d\n", i

不通过传值传指针传引用而实现形参修改实参的值

1.首先了解一下堆栈帧的创建步骤(来自<32位汇编语言程序设计>钱晓捷一书): 1)主程序把传递的参数压入堆栈: 2)调用子程序时,返回地址压入堆栈: 3)子程序中,EBP压入堆栈:设置EBP等于ESP,通过EBP访问参数和局部变量: 4)子程序有局部变量,ESP减去一个数值,在堆栈预留局部变量使用的空间: 5)子程序要保护的寄存器压入堆栈. 如下图: 2.了解了堆栈帧之后,就可以得出以下程序: 1)嵌入汇编实现 #include<iostream> using namespace

指针做形参做局部变量以及内存分配

指针做形参做局部变量以及内存分配 一级指针做形参:首先一定要明白形参和你传递参数的那个实参是两个不同的变量,即使同名也还依然不同.指针传递的是一个变量或者一个值的地址,但是它本身还是采用值传递的方式.即你不能使它指向另外一块地址,但是你可以改变它指向的空间里存的值. 二级指针做形参:二级指针也是传值,但是他指向的地址是个一维指针,所以可以改变二维指针指向的地址空间里的内容也就是要申请空间的一维指针,不能改变二维指针本身的值,即不能让他指向一个新的一维指针.所以二维指针传递的是一个一维指针. 具体

(转)java中形参与实参的区别

实参(argument): 全称为"实际参数"是在调用时传递给函数的参数. 实参可以是常量.变量.表达式.函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参. 因此应预先用赋值,输入等办法使实参获得确定值. 形参(parameter): 全称为"形式参数" 由于它不是实际存在变量,所以又称虚拟变量.是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数.在调用函数时,实参将赋值给形参.因而,必须