基础
函数的形参都是原数据的“副本”,在函数自己栈中申请内存 函数中参数都是传值,传指针本质上也是传值 如果想要改变入参内容,则需要传该入参的地址(指针和引用(c++)都是类似的作用)
形参与实参
普通变量参数
函数内部用的参数是形参,传入函数的参数是实参 形参会在函数栈空间再开辟内存,复制实参的内容 函数结束后,栈空间,形参也随之消失
#pragma warning(disable:4996)
#include <stdio.h>
void test ( int a)
{
printf ( "形参地址:%x,值:%d\n" , & a, a) ;
return ;
}
int main ( int argc, char * argv[ ] )
{
int a = 10 ;
printf ( "实参地址:%x,值:%d\n" , & a, a) ;
test ( a) ;
system ( "pause" ) ;
return 0 ;
}
指针作为参数
指针参数
函数不需要再为形参开辟存储int类型的空间
#pragma warning(disable:4996)
#include <stdio.h>
void test ( int * a)
{
* a = * a + 1 ;
printf ( "改变中,形参地址:%x,值:%d\n" , a, * a) ;
}
int main ( int argc, char * argv[ ] )
{
int a = 10 ;
printf ( "改变前,实参地址:%x,值:%d\n" , & a, a) ;
test ( & a) ;
printf ( "改变后,实参地址:%x,值:%d\n" , & a, a) ;
system ( "pause" ) ;
return 0 ;
}
本质是为形参开辟了指针类型的空间(所以形参就是副本,即使传入的是指针类型,不过是两个不同地址的指针指向同一个地址而已)
#pragma warning(disable:4996)
#include <stdio.h>
void test ( int * a)
{
printf ( "形参指针地址:%x\n" , & a) ;
}
int main ( int argc, char * argv[ ] )
{
int a = 10 ;
int * p = & a;
printf ( "实参指针地址:%x\n" , & p) ;
test ( p) ;
system ( "pause" ) ;
return 0 ;
}
数组参数
数组名本身就是指针
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void print01 ( int * arr, int len)
{
for ( int i = 0 ; i < len; i++ )
{
printf ( "%d\n" , arr[ i] ) ;
}
}
int main ( int argc, char * argv[ ] )
{
int arr[ ] = { 1 , 2 , 3 , 4 , 6 , 0 , 7 , 8 , 9 , 10 } ;
print01 ( arr, sizeof ( arr) / sizeof ( arr[ 0 ] ) ) ;
system ( "pause" ) ;
return EXIT_SUCCESS;
}
返回
#pragma warning(disable:4996)
#include <stdio.h>
int * test ( int a)
{
printf ( "形参地址:%x,值:%d\n" , & a, a) ;
return & a;
}
int main ( int argc, char * argv[ ] )
{
int a = 10 ;
printf ( "实参地址:%x,值:%d\n" , & a, a) ;
int * p = test ( a) ;
printf ( "返回地址:%x,值:%d\n" , p, * p) ;
system ( "pause" ) ;
return 0 ;
}