C语言专题 ④小知识点

小知识点(1)

  • 数组作为函数参数
  • 指针变量做函数参数

1.数组作为函数参数

例:(整形数组)简单的输入输出

输出为函数,主要探讨数组作为函数参数时的意义。

#include<stdio.h>
void Output(int a[]);
int main()
{
	int i;
	int a[5];
	for(i=0;i<5;i++)       //整型数组的读入
	{
		scanf("%d",&a[i]);
	}
	Output(a);
	return 0;
}
void Output(int a[])    //整型数组的输出
{
	int i;
	for(i=0;i<5;i++)
	{
		printf("%d",a[i]);
	}
	printf("\n");
}

那实参跟形参是否一样呢?
先做一个实验。
大家知道对数组名用sizeof,求得的将会是整个数组的长度,那么对形参呢?

void Output(int a[])    //在输出函数中加入sizeof运算符;
{
 int i;
 for(i=0;i<5;i++)
 {
  printf("%d",a[i]);
 }
 printf("\n");
 printf("sizeof(a)=%d",sizeof(a));
}

我的输出结果是sizaof(a)=8(有的电脑可能是4)
这个例子说明,存在形参里面,即函数里面的a实际上只是一个指针变量,里面存放是的主函数中a的地址,而c中指针变量的长度是4(有的是8,跟操作系统相关)
所以,此处对int a[]的声明也相当于int *a;

使用[]的好处就是可以显示的表示该参数将被作为指向数组的指针。
(就像定义指针变量,int *p中的*只是为了说明p这个变量时指针类型而不是单纯的整形变量,在这里并不起解引用的作用)

而值得注意的是:
①数组在内存中是连续储存的;实参数组在向函数的形参数组传递时,需要传递的只是数组的首地址(即数组名)和长度,而在传递实参时,如果写成a[10]系统只会检测数组名,而不会检测里面的内容([]内的任何常量表达式都会被忽略,而被自动转化为指针类型),所以数组长度需要另外定义一个变量来传递;

既然说传递的只是数组名及长度,并且函数形参中a只是一个指针变量,为什么像下面这样的程序可以输出原数组的长度(即操作原数组),而不需要写什么*a呢?
(改成以字符数组为例)

#include<stdio.h>
#include<string.h>
void Output(char a[]);
int main()
{
 int i;
 char a[5];
 for(i=0;i<5;i++)   //输入字符数组
 {
  scanf("%c",&a[i]);
 }
 Output(a);
 return 0;
}
void Output(char arrey[])    //输出字符数组
{
 int i;
 int x=strlen(arrey);    //使用了a这个形参(在此处是形参,即主函数中a[]数组的首地址)
 for(i=0;i<5;i++)
 {
  printf("%c",arrey[i]);
 }
 printf("\n");
 printf("len=%d",x);
}

原因:
strlensizeof的通性;
strlen()函数的原型为:unsigned int strlen (char *s); s为指定的字符串;
strlen()后面只需要字符数组的首地址即可。

而在函数中可以直接写arrey[5]=5之类的语句来改变原数组的值,是因为
此处的arrey是形参变量,已经存放了原数组a的首地址,就可以当作a来使用;
(此处相当于指针的用法了,如果在原函数中定义*p=a,再给p赋值p=a,这以后原数组a[]可以直接用*p*(p+1)或者p[]来代替,具体的可以参照指针跟一维数组的关系)




2.指针变量做函数参数(指针传参)

例:统计重复字符
编程并计算所输入字符串中连续重复出现次数最多的字符,输出该字符及次数

#include<stdio.h>
#include<string.h> 

int CountRepeatStr(char str[], int *tag);  //注意tag这个参数的用法
int main()
{
	 char s[81];
	 int count;	//统计出现的次数
	 int tag=0;	//统计次数最多的字符的下标(也可以让函数直接返回次数最多的字符)
	 printf("Input a string:\n");
	 gets(s);
	 count=CountRepeatStr(s,&tag);
	 printf("%c:%d\n",s[tag],count);
	 
	 return 0;
}

int CountRepeatStr(char str[], int *tag)
{
	 int l=strlen(str);
	 int i;
	 int max=1;
	 int count=1;
	
	 for(i=0;i<l;i++)
	 {
	 	if(str[i] == str[i+1])
	 	{
	 		count++;
	 		if(count>max)
	 		{
	 			max=count;
	    			*tag=i+1;
	   		}
		}
		else if(str[i]!=str[i+1])
		{
	 		count=1;
		}
	}
	return max;
}

(可以小小的注意一下这道题的算法)

再总结一下这个程序中tag的用法:
主函数给被调函数传的值为tag这个变量的地址,而在被调函数中定义了一个新的变量也叫tag,里面存放的是原函数tag参数的地址,被调函数中的*tag就相当于访问了主函数tag变量的值(被调函数跟主函数中的tag变量不一样)

这个函数并没有再多专门定义一个指针变量,需要加深理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值