指针作为参数的经典例子



#include "stdafx.h"
#include <stdio.h>
//输出型参数
void Swap(int *a , int *b)
{
	int t = *a ;
	*a = *b;
	*b = t;
}
//输入型参数
void Swap1(int *a , int *b)
{
	int *t = a;
	a = b;
	b = t;
}
//输入型参数
void Swap2(int a , int b)
{
	int t = a;
	a = b;
	b = t;
}
//多个返回值的输出可以考虑使用输出型参数
void Test(int a , int b , int *pPlus , int *pDec)
{
	*pPlus = a + b;
	*pDec = a - b;

}
int main(int argc, char* argv[])
{
	//指针变量作形式参数时,经常用于改变主调函数的实参数值
	//(使用取值符号*或者下标[]来远程操作实参)
	//这种被调函数的形式参数我们称之为:输出型参数
	
	int x = 20 , y = 10;
	Swap(&x,&y);
	Swap1(&x,&y);
	Swap2(x,y);

	int nPlus,nDec;
	Test(x,y,&nPlus,&nDec);


	return 0;
}

<think>嗯,用户想了解C语言中指针作为参数传入的情况。首先,我需要确定用户的基础知识水平。可能他们刚学指针,对这部分概念感到困惑。指针作为参数传递,主要涉及函数参数的传递方式和指针的基本概念。 首先,回忆一下C语言中函数参数的传递都是值传递,也就是说,函数内部得到的是实参的一个副本。当传递指针时,实际上传递的是指针变量的值,也就是地址的副本。这样在函数内部可以通过这个地址修改原变量的值,这是指针作为参数的主要用途之一。 接下来,需要解释为什么使用指针作为参数。通常是为了实现函数内外数据的双向传递,或者需要传递较大的数据结构时避免拷贝开销。比如,交换两个变量的值的经典例子,如果不使用指针,函数内部交换的只是副本,原变量不会改变。而使用指针后,可以通过地址直接修改原变量的值。 然后,考虑用户可能的疑问点。比如,指针和数组的关系,指针作为参数时如何影响原数据,以及可能的错误用法,比如空指针或野指针的问题。需要提醒用户注意这些常见错误,并提供示例说明正确的用法。 还需要区分指针作为参数和普通变量作为参数的不同之处。通过对比,用户能更清楚地理解指针的优势和适用场景。例如,在函数内修改普通变量不会影响外部变量,而通过指针可以改变外部变量。 另外,可能需要提到const修饰符在指针参数中的使用,比如防止意外修改指向的数据,增加代码的安全性。这也是一个重要的知识点,特别是当函数不需要修改数据时,使用const可以避免错误。 最后,总结指针作为参数的应用场景,比如动态内存分配、大型结构体或数组的处理,以及需要函数返回多个值的情况。这些实际应用能帮助用户更好地理解其重要性。 在组织回答时,应该按照逻辑顺序,从基本概念到具体应用,逐步深入。确保每个步骤都有示例代码,并解释代码的执行结果,这样用户能直观地看到指针作为参数的效果。同时,注意提醒常见的错误和注意事项,帮助用户避免实际编程中的陷阱。</think>C语言中指针作为参数传入是函数参数传递的重要机制,下面分步骤进行讲解: 一、基本概念 1. 指针参数本质:传递的是变量的内存地址 2. 语法格式:`返回值类型 函数名(类型* 指针参数)` 3. 内存示意图: ``` 主调函数变量地址 0x7ffe 被调函数指针参数(存储相同地址) ↓ 实际数据存储位置 ``` 二、典型应用场景 1. 修改外部变量值(实现函数副作用) ```c void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } // 调用:swap(&x, &y) ``` 2. 处理数组数据 ```c void arrayProcess(int* arr, int size) { for(int i=0; i<size; i++){ arr[i] *= 2; // 等价于 *(arr+i) } } ``` 3. 动态内存操作 ```c void createArray(int** ptr, int size) { *ptr = (int*)malloc(size * sizeof(int)); } // 调用:int* arr; createArray(&arr, 10); ``` 三、与普通参数的区别 | 参数类型 | 内存操作 | 变量作用域 | 效率 | |----------|-----------------|------------|-----------| | 普通参数 | 值拷贝 | 函数内部 | 低 | | 指针参数 | 地址引用 | 全局影响 | 高 | 四、使用注意事项 1. 必须验证指针有效性 ```c if(ptr == NULL) { // 错误处理 } ``` 2. 多级指针的使用(以二维数组为例) ```c void matrixOp(int** mat, int rows, int cols) { // 矩阵操作... } ``` 3. const修饰符的正确使用 ```c // 防止意外修改 void readData(const int* ptr) { // *ptr = 10; // 编译错误 } ``` 五、常见错误示例 1. 野指针问题 ```c void dangerFunc(int* p) { int x = 10; p = &x; // 危险!函数返回后x的内存被回收 } ``` 2. 地址运算符遗漏 ```c int num = 5; // 错误调用:increment(num); // 正确应使用:increment(&num); ``` 六、性能优势分析 当传递大型结构体时: - 普通参数:拷贝整个结构体(时间/空间复杂度O(n)) - 指针参数:固定4/8字节传输(时间复杂度O(1)) 建议在以下情况使用指针参数: 1. 需要修改原始数据 2. 处理动态分配的内存 3. 传递大型数据结构 4. 需要实现多返回值函数 理解指针参数机制需要结合内存模型进行实践,建议通过调试器观察地址变化,加深对参数传递机制的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值