您的位置:首页 > 编程语言 > C语言/C++

C语言中数组指针 作为形参

2015-06-05 21:33 232 查看
2015 0605

在修改程序的过程中,看到两种将数组作为形参的方法,于是搜了一下,找了一下比较全面地介绍数组指针的文章。

先写下我遇到的两种方式:

方式1:

void filter_c(long double *,long double *,float *,int);//函数声明

filter_c(NAFF_b,NAFF_a,RealTimeSignal_filter,len_new);//函数应用

void filter_c(long double b[ ],long double a[ ],float x[ ],int number)//函数定义

{.............................}

方式2:

void select_sort(float *, int);//函数声明

select_sort(Buff_Flow, MaxSize);//函数应用

void select_sort(float *x, int n)//函数定义

{..............................}

原文地址:http://blog.sina.com.cn/s/blog_90832a850100wksp.html

数组元素
    数组元素可以用作函数实参,但不能用作形参。因为形参是在函数被调用时临时分配存储单元的,不可能为一个数组元素单独分配存储单元。

在用数组元素作函数实参时,把实参的值传给形参,是单向的“值传递”过程。

数组名

数组名作函数实参时,向形参(数组名或指针变量)传递的是数组首元素的地址。形参数组可以不指定大小,在定义数组时在数组后面跟一个空的方括号。形参数组名实际上是一个指针变量,并不是真正的开辟一个数组空间。相应的,定义实参数组时必须要指定数组大小,因为要开辟相应的存储空间。

例如:

#include <stdio.h>
int main()
{
void fun(int arr[],int n);
void output_fun(int * arr,int n);
int array[10];

fun(array,10);
output_fun(array,10);
return 0;
}
void fun(int arr[],int n)
{
int i;
for(i=0;i<n;i++)
scanf_s("%d",&arr[i]);
}
void output_fun(int * arr,int n)
{
int i;
for(i=0;i<n;i++,arr++)
printf("%-2d",* arr);
}

//void fun(int arr[],int n)和void fun(int * arr,int n)等价。//这里就是程序中遇到的两种方式。

指针与指针变量

一个变量的地址称为该变量的指针。

如果有一个变量是专门用来存放另一个变量的地址(即指针),则它称为指针变量。

指针变量就是地址变量,指针变量的值就是地址。

指针变量作为函数参数

主调函数的实参是指针变量,在函数调用时,将实参变量的值传递给形参变量,这里依然是单向的值传递,但是传递的内容是实参的地址。这就与数组名的传递是一样的道理。

不能通过执行调用函数来改变实参指针变量的值,但可以改变实参指针变量所指变量的值。

归纳:数组名与指针变量

(1)形参和实参都用数组名;

(2)实参用数组名,形参用指针变量;

(3)实参和形参都用指针变量;

(4)实参为指针变量,形参用数组名。

值得注意的是:如果用指针变量作为实参,必须先使指针变量有确定值,指向一个已定义的对象。

数组元素的指针

引用数组元素可以用下标法(如a[i]),也可以用指针法(如*(a+i)或*(p+i))。下面这几种写法等价,都是使指针变量p指向数组a的首地址。其中a为已定义的数组名。

(1)int * p=&a[0];

(2)int * p=a;

(3)int * p;p=a;

(4)int * p;p=&a[0];

在指针指向数组元素时,可以对指针进行以下运算:

加一个整数(+或+=);

减一个整数(-或-=);

自加运算;

自减运算;

两个指针相减,如p1-p2(只有p1和p2都指向同一数组中的元素时才有意义)。

指针就是地址,两个指针相减可知道它们所指向元素的相对距离。地址不能相加,如p1+p2是无实际意义的。

二维数组a[][]

二维数组名(如a)是指向行的。因此a+1中的“1”代表一行中全部元素所占的字节数。

一维数组名(如a[0],a[1])是指向列元素的。a[0]+1中的1代表一个a元素所占的字节数。

在指向行的指针前面加一个*,就转换为指向列的指针。如,*a和*(a+1),分别指向a数组的0行0列的元素和1行0列的元素。

在指向列的指针前面加&,就成为指向行的指针。如,a[0]指向的是0行0列元素的指针,在前面加一个&之后,由于a[0]与*(a+0)等价,因此&a[0]与&*a等价,也就是与a等价,它指向二维数组的0行。

指向多维数组的指针变量

(1)指向数组元素的指针变量

举个例子,指向二维数组元素的指针变量

#include <stdio.h>
int main(void)
{
void input_output_array_fun(int *);
int a[3][4];
int * pointer;
pointer=a[0]; //这里使指针变量pointer指向0行0列元素地址。
input_output_array_fun(pointer);
return 0;
}
void input_output_array_fun(int * p)
{
int i;
for(i=0;i<12;i++)
scanf_s("%d",p+i);
for(i=0;i<12;i++)
{
printf("%-5d",*(p+i));
if((i+1)%4==0)printf("\n");
}//for
}

(2)指向由m个元素组成的一维数组的指针变量

如int (* p)[4],p的类型是int(*)[4],p被定义为指向一维整型数组的指针变量,一维数组有4个元素,因此p的基类型是一维数组,其长度为16字节。

#include <stdio.h>
int main(void){
void input_output_array_fun(int (* p) [4]);
int a[3][4];
int (* pointer)[4];
pointer=a; //这里使指针变量pointer指向0行。
input_output_array_fun(pointer);
return 0;
}
void input_output_array_fun(int (* p)[4]){
int i,j;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
scanf_s("%d",*(p+i)+j);
for(i=0;i<3;i++)
for(j=0;j<4;j++)
{
printf("%-5d",*(*(p+i)+j));
if(j==3)printf("\n");
}//for(i=0;)
}

通过指针引用字符串

通过字符数组名或者字符指针变量可以输出一个字符串,而对一个数值型数组,是不能企图用数组名输出它的全部元素的,只能逐个输入。

字符数组从键盘输入的时候调用gets_s()函数;

数值型数组从键盘输入的时候调用scanf_s()函数。

字符指针变量和字符数组的比较

(1)字符指针变量中存放的是地址。字符数组由若干个元素组成,每个元素中存放一个字符。

(2)可以对字符指针变量赋值。不能对字符数组名赋值。如:

char *a;

a="I care."; //合法

char str[10];

str="I care."; //非法

str[0]="I";//合法。一旦字符数组没有在初始化时赋值,只能逐个赋值。

(3)初始化。

字符指针变量:

char *a="I care.";

等价于

char *a;

a="I care.";

字符数组:

char str[10]="I care."; //合法

不等价于

char str[10];

str[]="I care.";//不能用赋值语句对字符数组中全部元素整体赋值。

(4)字符指针变量在编译时,只分配一个存储单元(用来存放字符串的起始地址)。字符数组在编译时会分配若干存储单元,以存放各元素的值。

(5)指针变量的值是可以改变的。数组名代表一个固定的值(数组首元素的地址),不可改变。

(6)字符指针变量所指向的字符常量中的内容是不可以被取代的(不能对它们再赋值),字符数组中各元素的值是可以改变的。如:

char a[]="you.";

char *b="you.";

a[1]='a'; //合法

b[1]='a'; //非法

(7)引用数组元素时,字符数组可以用下标法引用一个数组元素(如a[2]),也可以用地址法(如*(a+2)引用数组元素a[2])。如果定义了字符指针变量p,并使它指向了数组a的首元素,则可以用指针变量带下标的形式引用数组元素(如p[5]),同样可以用地址法(如*(p+5))引用数组元素a[5]。

(8)用指针变量指向一个格式字符串,能轻松实现可变格式输出函数。如:

char *p;

p="a=%d,b=%f\n";

printf(p,a,b);

相当于

printf("a=%d,b=%f\n",a,b);

使用字符数组也能达到这一目的,但只能在定义数组时初始化或逐个对元素赋值的方法。显然指针变量指向字符串的方式更为方便。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: