C语言教程:指针与数组(三)
由于C程序的函数调用是采用传值调用,即实际参数与形式参数相结合时,实参将值传给形式参数,所以当我们利用函数来处理数组时,如果需要对数组在子程序中修改,只能传递数组的地址,进行传地址的调用,在内存相同的地址区间进行数据的修改。
在实际的应用中,如果需要利用子程序对数组进行处理,函数的调用利用指向数组(一维或多维)的指针作参数,无论是实参还是形参共有下面四种情况:
我们知道,二维数组在内存中是按行存放,假定我们定义二维数组和指针如下:
int a[3][4],* p = a [ 0 ] ;
则指针p就指向二维数组。其在内存的存放情况如图6 - 11所示。
从上述存放情况来看,若把二维数组的首地址传递给指针p,则映射过程如图6 - 11
所示。我们只要找到用p所表示的一维数组中最大的元素及下标,就可转换为在二维数组中的
行列数。
# include<stdio.h>
m a i n ( )
{
int a[3][4],*ptr,i,j,max,maxi,maxj;
/ * m a x 是数组的最大, m a x i 是最大元素所在行, m a x j 是最大元素所在列* /
f o r ( i = 0 ; i < 3 ; i + + )
f o r ( j = 0 ; j < 4 ; j + + )
s c a n f ( " % d " , & a [ i ] [ j ] ) ;
p t r = a [ 0 ] ; / * 将二维数组的首地址传递给指针变量* /
m a x _ a r r ( p t r , & m a x , & m a x i , 1 2 ) ;
m a x j = m a x i % 4 ; / * 每行有四个元素,求该元素所在列* /
m a x i = m a x i / 4 ; / * 求该元素所在行* /
printf("max=%d,maxi=%d,maxj=%d",max,maxi,maxj);
}
int max_arr(b,p1,p2,n)
int *b,*p1,*p2,n;
/ * b 指向二维数组的指针, p 1指向最大值,p 2 指向最大值在一维数组中的位置, * /
/ * n 是数组的大小* /
{
int i;
*p1=b[0]; *p1=0;
f o r ( i = 1 ; i < n ; i + + ) / * 找最大* /
if (b[i]>*p1) {*p1=b[i]; *p2=i;}
}
运行程序:
6.4.4 指针与字符数组
在前面的课程中,我们用过了字符数组,即通过数组名来表示字符串,数组名就是数组的首地址,是字符串的起始地址。下面的例子用于简单字符串的输入和输出。
#include<stdio.h>
main()
{
char str[20];
gets(str);
printf("%s\n",str);
}
现在,我们将字符数组的名赋予一个指向字符类型的指针变量,让字符类型指针指向字
符串在内存的首地址,对字符串的表示就可以用指针实现。其定义的方法为:charstr[20],
*P=str;这样一来,字符串str就可以用指针变量P来表示了。
#include<stdio.h>
main()
{
char str[20],*p=str;/*p=str则表示将字符数组的首地址传递给指针变量p*/
gets(str);
printf("%s\n",p);
}
RUN
good morning!
goodmorning!
需要说明的是,字符数组与字符串是有区别的,字符串是字符数组的一种特殊形式,存储时以“\0”结束,所以,存放字符串的字符数组其长度应比字符串大1。对于存放字符的字符数组,若未加“\0”结束标志,只能按逐个字符输入输出。
[例6-18]字符数组的正确使用方法。
#include<stdio.h>
main()
{
charstr[10],*p=str;
int i;
scanf("%s",str);/*输入的字符串长度超过10*/
for(i=0;i<10;i++)
printf("%c",*p++);/*正确输出*/
printf("\n");
p=str;
printf("%s",p);/*字符数组无'\0'标志,输出出错*/
puts(str);/*字符数组无'\0'标志,输出出错*/
}
对上述程序中字符数组以字符串形式输出,若无“\0”标志,则找不到结束标志,输出出
错。
[例6-19]用指向字符串的指针变量处理两个字符串的复制。
字符串的复制要注意的是:若将串1复制到串2,一定要保证串2的长度大于或等于串1。
#include<stdio.h>
main()
{
char str1[30],str2[20],*ptr1=str1,*ptr2=str2;
printf("inputstr1:");
gets(str1);/*输入str1*/
printf("inputstr2:");
gets(str2);/*输入str2*/
printf("str1------------str2\n");
printf("%s.......%s\n",ptr1,ptr2);
while(*ptr2)*ptr1++=*ptr2++;/*字符串复制*/
*ptr1='\0';/*写入串的结束标志*/
printf("str1------------str2\n");
printf("%s.......%s\n",str1,str2);
}
在程序的说明部分,定义的字符指针指向字符串。语句while(*ptr2)*ptr1++=*ptr2++;先测试表达式的值,若指针指向的字符是“\0”,该字符的ASCII码值为0,表达式的值为假,循环结束,表达式的值非零,则执行循环*ptr1++=*ptr2++。语句*ptr1++按照运算优先级别,先算*ptr1,再算ptr1++。
现在,我们修改程序中语句printf("%s.......%s\n",str1,str2)为printf("%s.......%s\n",ptr1,ptr2);
会出现什么结果呢?请思考。
[例6-20]用指向字符串的指针变量处理两个字符串的合并。
#include<stdio.h>
main()
{
char str1[50],str2[20],*ptr1=str1,*ptr2=str2;
printf("inputstr1:");
gets(str1);
printf("inputstr2:");
gets(str2);
printf("str1------------str2\n");
printf("%s.......%s\n",ptr1,ptr2);
while(*ptr1)ptr1++;/*移动指针到串尾*/
while(*ptr2)*ptr1++=*ptr2++;串/*连接*/
*ptr1='\0';/*写入串的结束标志*/
ptr1=str1;ptr2=str2;
printf("str1------------------str2\n");
printf("%s.......%s\n",ptr1,ptr2);
}
需要注意的是,串复制时,串1的长度应大于等于串2;串连接时,串1的长度应大于等于串1与串2的长度之和。
进入C语言程序设计视频教程专区
Word教程网 | Excel教程网 | Dreamweaver教程网 | Fireworks教程网 | PPT教程网 | FLASH教程网 | PS教程网 |
HTML教程网 | DIV CSS教程网 | FLASH AS教程网 | ACCESS教程网 | SQL SERVER教程网 | C语言教程网 | JAVASCRIPT教程网 |
ASP教程网 | ASP.NET教程网 | CorelDraw教程网 |