一、数组的指针
1.数组与地址
2.数组元素的访问二、字符串指针
1.字符串指针的定义
2.字符指针与字符数组的区别三、指针作为函数参数
1.数组名作为函数参数
2.字符指针作为函数参数第 16讲 数组的指针和字符串的指针
C语言规定:
数组名代表数组(元素)的首地址,即第一个元素的地址。
若有,int a[10],*p=a;
则,a 与 & a[0] 是等价的指针变量 p 为数组的指针
数组的指针:数组的起始地址,即数组元素的首地址。
数组元素的指针:数组元素的地址。
一、数组的指针
1.数组与地址
对数组的首地址加上偏移量 x就可以得到其它元素的地址。
例,& a[1] 表示数组元素 a[1]的地址等价于 a+1,p+1
& a[x] 表示数组元素 a[x]的地址等价于 a+x,p+x
2.数组元素的访问
下标法:
用 a[i] 的形式存取数组元素。
地址法,
用 *( a+i) 的形式存取数组元素。
指针法,
用指针变量 p指向数组的首地址,然后通过移动指针存取数组元素。
如 p=a,p+i。
例 a 用 下标法 存取数组元素
main( )
{ int a[10],i;
for ( i=0; i<10; i++ )
scanf("%d",&a[i]);
for ( i=0; i<10; i++ )
printf("%d",a[i]);
printf("\n");
}
例 b 用 地址法 存取数组元素
main( )
{ int a[10],i;
for ( i=0; i<10; i++ )
scanf("%d",a+i );
for ( i=0; i<10; i++ )
printf("%d",*(a+i));
printf("\n");
}
数组元素的访问举例例 c 用指针法存取数组元素。(即通过指针指向数组的首地址,然后通过移动指针存取数组元素。)
main( )
{ int a[10],*p,i;
for (i=0,p=a; i<10; i++)
scanf("%d",p+i);
for (i=0,p=a; i<10; i++)
printf("%d",*(p+i));
printf("\n");
}
main( )
{ int a[10],*p;
for ( p=a; p<a+10; p++)
scanf("%d",p);
for ( p=a; p<a+10; p++)
printf("%d",*p);
printf("\n");
}
例 c 说明
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
0
2
4
6
8
p = & a
*p++
*p
p++
等价于数组元素的访问小结,
int i,a[10],*p=a;
表 现 形 式 含 义
&a[0] a p 一维数组首地址
&a[ i ] a+i p+i 一维数组下标为 i 的元素地址
a[0] *a *p 一维数组下标为 0 的元素的值
a[ i ] *(a+i) *(p+i) 一维数组下标为 i 的元素的值注意:
数组名是一个常量,不允许重新赋值。
指针变量是一个变量,可以重新赋值。
p+i和 a+i均表示数组元素 a[i]的地址,均指向
a[i]。
*(p+i)和 *(a+i)均表示 p+i和 a+i所指对象的内容,
即 a[i]。
*p++,等价于 *(p++)。 其作用:先得到 *p,再使 p=p+1。
(*p)++:表示将 p所指向的变量(元素)的值加 1。
即等价于 a[i]++ 。
例,int a[5]={0,2,4,6,8},*p;
p=a+2;
(*p)++;
printf( "%d\n",*p ) ;
程序段输出为,5

main( )
{ int a[5]={0,2,4,6,8},*p,x;
p=a; (*p)++;
p=a+1; ++(*p);
p=a+2; (*p)--;
p=a+3; --(*p);
for (x=0;x<=4;x++)
printf("%d ",a[x] );
printf("\n");
}
程序运行结果,
1 3 3 5 8
指向数组元素的指针也可以表示成数组的形式,
即允许指针变量带下标,如 *(p+i)可以表示成 p[i]。
但需注意,如果 p不指向 a[0],则 p[i]和 a[i]是不一样的。
如 p=a+3;
由于 p指向 a[3],所以 p[3]就相当于 a[6]而不是 a[3]。
这种方式容易出错,一般不提倡使用。
字符串的处理是用字符型数组来实现的。
用 char型数组处理的字符串都可以用 char型指针来处理。通常把 char型指针称为字符串指针或字符指针。
二、字符串指针在程序中定义一个字符指针变量,并将字符串的首地址赋给它,然后通过字符指针变量来访问字符串 。
例如:
char str[ ]="C programming";
char *p;
p=str;
或:
char *str="C programming";
1.字符串指针的定义例,
/* 用字符数组实现字符串操作 */
main( )
{
char str[]="Welcome to study C !";
int i;
printf("%s\n",str);
for (i=0;i<=7;i++)
printf("%c",str[i]);
printf("\n");
}
程序运行结果为:
Welcome to study C !
Welcome

/* 用字符指针实现字符串操作 */
main()
{ char *str="Welcome to study C !";
int i;
printf("%s\n",str);
for(i=0;i<=7;i++)
printf("%c",*(str+i));
printf("\n");
}
字符指针与字符数组的区别
字符数组是由若干个元素组成,每个元素存放一个字符;而字符指针变量存放的是字符串的首地址 。
赋值方式不同 。 字符数组只能对各个元素分别赋值,而字符指针只需赋给字符串的首地址就可以了 。
字符指针占用的内存要少于字符数组 。
指针变量的值是可以改变,而字符数组的数组名虽然代表地址,但它的值是不会变化 。
区别举例:
如,char *str;
str="Welcome to study C ! ";
以下对字符数组的赋值是错误的:
char str[80];
str[ ]="Welcome to study C ! ";
例 将字符串 s1复制到字符串 s2。
main( )
{ char s1[ ]=“copy string”,s2[30];
char *p1=s1,*p2=s2;
int i;
for ( ; *p1!=?\0?; p1++,p2++) *p2=*p1;
*p2=?\0?;
printf(“string s2=”);
for (i=0; s2[i]!=?\0?; i++)
printf(“%c”,s2[i]);
printf(“\n”);
}
程序运行结果为:
string s2=Copy string
1.数组名作为函数参数特点:
数组名表示数组元素的首地址。
在函数调用时,传递的是数组元素的首地址。
实参与形参的传递是,值传递,。
实参数组与形参数组共用一段存储单元。
可以用指向数组的指针变量作函数的参数。
三、指针作为函数参数以下列出实参和形参使用数组名或指针变量的四种情况:
实参,数组名 数组名 指针变量 指针变量形参,数组名 指针变量 数组名 指针变量例,已知一个一维数组 a[11]中有 10个数,求出其中前 n个数的和,并放入 a[10]中。其中 n由键盘输入。
#include <stdio.h>
sum(int *q,int n)
{ int i,s=0;
int *t;
t=q; /* t与 q都指向数组 a的第一个元素 */
for (i=0;i<n;i++,q++)
s+=*q;
*(t+10)=s; /* t+10指向数组元素 a[10] */
}
main()
{
int num,a[11]={1,2,3,4,5,6,7,8,9,10};
int *p=a;
scanf ("%d",&num);
sum(p,num);
printf("%d\n",a[10]);
}
将一个字符串从一个函数传递到另一个函数,
可以使用地址传递的方法,即用字符数组名作为参数或用指向字符串的指针变量作为参数。
在被调用函数中可以改变字符串的内容,而在主调函数中可以得到被改变了的字符串。
由于字符串是按照字符数组形式存储的,所以对字符串中字符的引用也可以用下标法或指针法。
2.字符指针作为函数参数例 设有两个字符串 "Hello"和 " World!",
试将它们连接在一起成为一个字符串。
main( )
{ char str1[15]="Hello",str2[]=" World!";
int i;
strcat(str1,str2);
printf("String str1=%s\n",str1);
}
strcat(char *s,char *t)
{ while(*s!='\0')
s++; /* 使 s指向字符串 str1的末尾 */
while(*t!='\0')
{ *s=*t; t++; s++; }
*s='\0'; /* 在 s后加上字符串结束标志 */
}
程序运行结果为:
String str1=Hello World!
例 输入一串小写字符将其转换为大写字符
main()
{ int i;
char a[100];
printf(“Input\n”);
scanf(“%s”,a);
utol( a ) ;
printf( "%s\n",a );
}
utol( char *x )
{ int i;
for ( i=0; *(x+i)!='\0'; i++ )
*(x+i)-=32;
}
例,编写一个函数 string_cut(char *str,char c),如果字符串 str 中包含字符变量 c,则输出其后的字符序列,否则输出空字符。
#include <stdio.h>
string_cut(char *str,char c)
{
for (;*str!='\0'&&*str!=c;str++);
puts(str);
}
void main()
{
char string[20]="Beijing";
char ch;
scanf("%c",&ch);
string_cut(string,ch);
}
例,有 3个字符串存放在一维指针数组中,编写一个程序,找出 3个串中 ASCII码最大的一个字母并输出。
分析:类似于二维数组,在每个字符串中查找最大的字母。
#include <stdio.h>
char max(char *s[ ])
{int i;
char ch,*p;
ch=s[0][0];
for (i=0;i<3;i++)
{ p=s[i];
for (; *p;p++)
if(*p>ch) ch=*p;
}
return ch;}
void main( )
{
char *str [ ]={“sfawe”,”fghj”,”abcrs”},c;
c=max(str);
printf(“Max=%c \n”,c);
}
程序运行结果为:
Max=w