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)还会正确吗?








  • 相关阅读:
    Azure PowerShell (7) 使用CSV文件批量设置Virtual Machine Endpoint
    Windows Azure Cloud Service (39) 如何将现有Web应用迁移到Azure PaaS平台
    Azure China (7) 使用WebMetrix将Web Site发布至Azure China
    Microsoft Azure News(4) Azure新D系列虚拟机上线
    Windows Azure Cloud Service (38) 微软IaaS与PaaS比较
    Windows Azure Cloud Service (37) 浅谈Cloud Service
    Azure PowerShell (6) 设置单个Virtual Machine Endpoint
    Azure PowerShell (5) 使用Azure PowerShell创建简单的Azure虚拟机和Linux虚拟机
    功能代码(1)---通过Jquery来处理复选框
    案例1.用Ajax实现用户名的校验
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10014609.html
Copyright © 2011-2022 走看看