zoukankan      html  css  js  c++  java
  • 指针知识梳理3-指针作为參数

    一、函数传參复习

    #include <stdio.h>
    //指针传參,函数传參本质是值传递
    
    void  func1(int a)
    {
    		a = 5;	
    }
    void  func2(int *p)
    {
    		*p  = 10;	
    		p++;
    }
    int main()
    {
    		int a = 0;
    		int *p  = &a;
    		//a 的值会变么?
    		func1(a);
    		printf("%d
    ",a);
    		func2(&a);
    		printf("%d
    ",a);
    		
    		//这里p的值会变么?
    		printf("p = %p",p);
    		func2(p);
    		printf("p = %p",p);
    }
    


    
    

    对于 func1来说,形參为int a,形參a是func1函数的一个局部变量。

    在main函数中,也有一个int a,这个a 是main函数中的局部变量。

    当调用 fucn1(a)的时候。仅仅是把main函数中的a的值传递给了func1函数的a变量。

    画内存图例如以下:

    当运行func1函数中 a = 5的时候。是在给func1函数中的变量a 赋值,对main函数中的变量没有不论什么影响,因此运行完func1的时候,main函数中的a值不变。

    main函数中a的值不变的原因是在func1函数中不能訪问main函数中变量a的内存。

    二、指针作为參数

    func2函数的形參是 int *p ,是一个指针变量。存储地址。

    当函数调用的时候 func2(&a), 相当与int *p = &a。 p存储的是a的地址,那么在函数func2中就知道了main函数中a的地址,知道了a的地址就能訪问a的内存。

    当在函数func2中 *p = 10的时候,是通过p存储的地址找到main函数中的a ,并赋值。

    当func2(&a)调用完成以后,main函数中a的值改变。

    --------------------------------------------------------------------------------------------------------

    再看例如以下:

    在main 函数中另一个变量 int *p = &a。当 func2(p)的时候,事实上原理跟 一 分析的情况是一样的。

    在func2函数中有一个局部变量 p ,在 main 函数中也有一个局部变量 p;

    当在main 函数中

    p = &a;

    func2(p);

    的时候。我们画出以下内存图:

    当在func2中 运行 *p = 10,p++的时候,改动了两块内存

    (1)通过func2中的p找到main函数中a,并改动a的额牛才干

    (2)改动func2中p本身的内存。

    main函数中的 p的内存并没有改变,p的值并没有变。

    依据以上方法,大家画以下内存图,观察变化。

    #include <stdio.h>
    
    void swap1(int a,int b)
    {
    		int temp  = a;
    		a = b;
    		b = temp;			
    	
    }
    void swap2(int *pa,int *pb)
    {
    	
    		int temp  = 0;
    		temp = *pa;
    		*pa = *pb;
    		*pb = temp;		
    		
    		/*
    		//错误点在哪里?
    		int *ptemp;
    		*ptemp  = *pa;
    		*pa = *pb;
    		*pb = *ptemp;
    		
    		*/	
    }
    Int main()
    {
    	int a = 0;
    	int b = 1;
    	swap1(a,b);
    	printf("a = %d,b = %d
    ",a,b);
    	swap2(&a,&b);
    	printf("a = %d,b = %d
    ",a,b);
    	
    }


    三、数组名作为參数

    1 、数组名作为參数的时候,本质上数组第一个元素的地址。

    曾经在学函数的时候简单提到:

    int  func1(int  a[10]);

    int  func2(int  a[4]);

    int  func3(int  a[ ]);

    中括号中面的数字没有不论什么意义。

    上面三种写法等效于

    int func4(int  *p);

    func1  func2  func3 的a就是指针变量。仅仅只是写法不一样,记住语法就可以。

    可以用例如以下代码解释和验证。

    #include <stdio.h>
    
    /*
    数组名的含义
    */
    int func1(int a[10])
    {
    	printf("%d
    ",sizoef(a));	 //指针,4个字节(32位)
    	
    }
    int func2(int a[])
    {
    	printf("%d
    ",sizoef(a));	 //指针,4个字节(32位)
    	
    }
    int func3(int *p)
    {
    	printf("%d
    ",sizoef(p));	//指针,4个字节(32位)
    	
    }
    int main()
    {
    		int a[10];
    		
    		//在这里 a 是整个数组 大小是 10个int ,sizeof是c语言的keyword。不是函数
    		printf("sizeof a = %d
    ",sizeof(a));
    		
    		//在这里 a 是首元素的地址。
    		int *p = a;
    		printf("sizeof p = %d
    ",sizeof(p));
    		
    		//在函数中 a 是首元素的地址。
    		func1(a);
    		func2(a);
    		func3(a);
    	
    }
    

    总结数组名的含义

    int a[10];

    (1)代表整个数组,sizeof(a),这里是40。是整个数组的内存, sizeof不是函数。

    (2)代表第一个元素的地址 int *p = a,  func(a)。



    这也就能解释为什么传数组名的时候可以在函数中改动函数外面的数组的值,由于在函数中可以知道数组中每一个元素的地址。

    #include <stdio.h>
    /*
    函数传数组,数组名是首元素的地址
    */
    int func1(int *p) //这里有没有漏洞?
    {
    	for(int i = 0;i<10;i++)
    	{
    		p[i] = 2;	 //*(p+i) = p[i]
    	}	
    	return 0;
    }
    int func2(int a[]) //这里有没有漏洞?
    {	
    	for(int i = 0;i<10;i++)
    	{
    		a[i] = 1;	
    	}	
    	return 0;
    }
    
    
    int main()
    {
    	int a[10] = {0};
    	func1(a);
    	for(int i = 0;i<10;i++)
    	{
    		printf("%d
    ",a[i]);	
    	}	
    	func2(a);
    	for(int i = 0;i<10;i++)
    	{
    		printf("%d
    ",a[i]);	
    	}
    	return 0;
    }

    思考以上代码:

    假设 int a[5];

    调用func1(a)还会正确吗?








  • 相关阅读:
    【转载】分布式环境Raft一致性共识算法解读
    从码农到工程师:只要做到这6点
    产品思维的修炼–技术的必修课
    工具篇
    安全测试
    测试体会
    测试题目
    软件测试工具
    常见的性能测试方法
    性能测试在软件测试的周期位置
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10014609.html
Copyright © 2011-2022 走看看