第八章 指针
指针
指针和数组
指针和字符串
指针 数组和二级指针
指针和函数
8.1 指针变量 地址 内容
int x;
x = 3; printf(“%d”,x;)
x 2001 3
px 3000 2001
直接访问,
通过变量名直接访问地址间接访问:
把变量的地址放到另一变量中,使用时先找到后者的地址,从中取出前者的地址指针变量 地址 另一变量的地址变量 地址 内容
x 2001 3
px 3000 2001
指针变量 地址 另一变量的地址指针变量:存放地址的变量某个变量的地址指向指向
int x;
x = 3; printf(“%d”,x;)
8.1.1 指针 变量 的 定义指针变量所指向变量的类型
int *px;
px 是整型指针,指向整型变量
float *pf;
pf 是浮点型指针,指向浮点型变量
char *pc;
pc 是字符型指针,指向字符型变量类型名 *指针变量名 ;
类型名 * 指针变量名 ;
int *p1,*p2; 等价于 int * p1;
int * p2;
int *px;
注意,指针变量名是 px,不是 *px
8.1.2 指针的 基本操作
*p,p所 指向的 变量 a
a
3&a
p
*p
1,&和 *
& 取地址运算符
* 指针运算符 (间接访问运算符 )
int *p,a = 3;
p= &a; 把 a 的地址赋给 p,即 p 指向 a
a
3&a
p
*p
输入 5 7
输出:
3,3
5,5
7,7
10,10
main( )
{ int a = 3,*p;
p = &a;
printf(“%d,%d\n”,a,*p);
scanf(“%d”,&a);
printf(“%d,%d\n”,a,*p);
scanf(“%d”,p);
printf(“%d,%d\n”,a,*p);
*p = 10;
printf(“%d,%d\n”,a,*p);
}
例 8.1指针 运算
b
10&b
p2
*p2
输出:
100,10
100,10
a
100&a
p1
*p1
main( )
{ int a,b;
int *p1,*p2;
a = 100; b = 10;
p1 = &a;
p2 = &b;
printf(“%d,%d\n”,a,b);
printf(“%d,%d\n”,*p1,*p2);
}
例 8.2指针 运算
a
3&a
p
*p
指针运算注意事项
(1) 当 p= &a 后,*p 与 a 相同。
(2) int *p; 定义
*p =10; p所指 向 的变量
(3) &*p 与 &a 相同,是 地址
*&a 与 a 相同,是 变量
a
3&a
p
*p
当 p= &a 时
(4)
(*p)++ 等价于 a++
将 p所指 向 的变量值加 1
*p++ 等价于 *(p++)
先取 *p,然后 p 自加,此时 p不再指向 a
2、赋值 =
a
3&a
p1
p2= p1; p2 也指向 a
&a
p2
*p1
*p2
int *p1,*p2,a=3;
p1= &a;
把 a 的地址赋给 p1,即 p1 指向 a
输出:
10,100
例 8.3指针 赋值
main( )
{ int a,b;
int *p1,*p2;
a = 100; b = 10;
p1 = &a;
p2 = p1;
p1 = &b;
printf(“%d,%d\n”,*p1,*p2);
}
b
10
p1 a
100
p2
8.1.3 指针 变量 的 初始化例 8.4-1
void main( )
{ int a=1,b=2;
int *p1= &a,*p2=&b,*pt;
printf(“%d,%d\n”,*p1,*p2);
pt = p1; p1 = p2; p2 = pt;
printf(“%d,%d\n”,*p1,*p2);
}
b
2&b
p2
a
1&a
p1
b
2&a
p2
a
1&b
p1
8.1.3 指针 变量 的 初始化例 8.4-2
void main( )
{ int a=1,b=2;
int *p1= &a,*p2=&b,t;
printf(“%d,%d\n”,*p1,*p2);
t = *p1; *p1 = *p2; *p2 = t;
printf(“%d,%d\n”,*p1,*p2);
}
b
2&b
p2
a
1&a
p1
b
1&b
p2
a
2&a
p1
8.1.4 指针 作为函数的参数
swap1(int x,int y)
{ int t;
t = x;
x = y;
y = t;
}
输出:
3,5 a
3 5
b
x
3 5
y
x
5 3
y
例 8.5
main( )
{ int a=3,b=5;
swap1(a,b);
printf(“%d,%d\n”,a,b);
}
swap2(int *p1,int *p2)
{ int t;
t = *p1;
*p1 = *p2;
*p2 = t;
}
输出:
5,3
3 5
a b
p1 p2
5 3
值传递,地 址未变,
但存放的变量的值改变了
main( )
{ int a=3,b=5;
swap2(&a,&b);
printf(“%d,%d\n”,a,b);
}
swap3(int *p1,int *p2)
{ int *p;
p = p1; p1 = p2; p2 = p;
}
3 5
a b
p1 p2
值传递,形参指针的改变不会影响实参
main( )
{ int a=3,b=5;
swap2(&a,&b);
printf(“%d,%d\n”,a,b);
}
输出:
3,5
swap2(int *p1,int *p2)
{ int t;
t = *p1;
*p1 = *p2;
*p2 = t;
}
main( )
{ int a=3,b=5;
swap2(&a,&b);
……
}
要使某个变量的值通过函数调用发生改变
(1) 在主调函数中,把该变量的地址作为实参
(2) 在被调函数中,用形参(指针)接受地址
(3) 在被调函数中,改变形参(指针)所指向变量的值例 8.6-1 指针作为函数的参数
void p(int *a,int b)
{ *a = *a -1; b++;
}
void main( )
{ int x = 3,y = 5;
p(&x,y);
printf("%d,%d\n",x,y);
}
调用前 main,x = 3,y = 5
调用 p,*a b
3 5
2 6
调用后 main,x = 2,y = 5
将变量的地址作为实参,调用后,
该变量的值可能改变例 8.6-2
void p(int *a,int b)
{ *a = *a -1; b++;
}
void main( )
{ int x = 3,y = 4;
p(&y,x);
printf("%d,%d\n",x,y);
}
调用前 main,x = 3,y = 4
调用 p,*a b
4 3
3 4
调用后 main,x = 3,y = 3
例 8.6-3
void p(int *a,int b)
{ *a = *a -1; b++;
}
void main( )
{ int x = 3,y = 5;
p(&x,y);
printf("%d,%d\n",x,y);
p(&y,x);
printf("%d,%d\n",x,y);
}
调用前 main,x = 3,y = 5
第 1次调用 p,*a b
3 5
2 6
调用后 main,x = 2,y = 5
第 2次调用 p,*a b
5 2
4 3
调用后 main,x = 2,y = 4
例 7-9
自定义函数 dayofyear(year,month,day),返回该年的第几天 。
dayofyear(2000,3,1)返回 61
dayofyear(1981,3,1)返回 60
分析:
月 0 1 2 3…… 11 12
非闰年 0 31 28 31 30 31
闰年 0 31 29 31 30 31
int tab[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31}
{0,31,29,31,30,31,30,31,31,30,31,30,31}}
例 7-9
void dayofyear(int year,int month,int day)
{
int k,leap;
int tab[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31}
{0,31,29,31,30,31,30,31,31,30,31,30,31}};
leap=(year%4==0&&year%100!=0) || year %400==0;
for (k=1; k<month; k++)
day=day+tab[leap][k];
return day;
}
例 8-7
输入年和天数,输出对应的月和日 。
例如:输入 2000和 61,输出 3和 1。
自定义函数 monthday(year,yearday,pmonth,pday)
带回 2个结果,用 2个指针作为函数的参数 。
void main( )
{
int day,month,year,yearday;
void month_day(int year,int yearday,int *pmonth,int *pday);
printf("input year and yearday\n");
scanf("%d%d",&year,&yearday);
month_day(year,yearday,&month,&day);
printf("%d-%d\n",month,day);
}
例 8-7
void month_day(int year,int yearday,int *pmonth,int *pday)
{
int k,leap;
int tab[2][13]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
leap=year%4==0 && year%100!=0 || year%400==0;
for(k=1; yearday>tab[leap][k]; k++)
yearday = yearday - tab[leap][k];
*pmonth=k;
*pday=yearday;
}
8.2 指针 和数组
8.2.1 指针、数组、地址间的关系
8.2.2 数组名做为函数的参数
8.2.1 指针、数组、地址间的关系指针和数组有密切的关系任何由数组下标来实现的操作都能用指针来完成 。
int a[10];
a[0]
a[1]
a[9]
a[i]
数组名是一个指针它的值是数组首元素的地址即它指向数组的首元素
a
int *ap;
ap = &a[0];
ap 指向数组 a的首元素
a[0]
a[1]
a[9]
a[i]
a
a+1
a+i
a+9
*(a+i)&a[i]
或:
ap = a;
ap,
ap+i,
*(ap+i)a[i]的地址 &a[i]
a+i,ap+i
a[i] 相当于 *(a+i)
*(ap+i),ap[i]
a[0]
a[1]
a[9]
a[i]
a
a+1
a+i
a+9
*(a+i)&a[i]
ap,
for(i=0; i<10; i++)
printf(”%d”,*(a+i))
for(ap=a; ap<a+10; ap++)
printf(”%d”,*ap)
注意,数组名 a 是指针常量,不能 a++
for(i=0; i<10; i++)
printf(”%d”,a[i])
例:输出数组 a所有元素
1、数组元素作为函数实参函数形参为变量
(与变量作为函数实参相同,值传递)
2、数组名作为函数参数由于数组名是指针常量,相当于指针作为函数的参数数组名做为实参形参是指针变量(数组)
8.2.2 数组名作为函数的参数
float average( float *array)
{ int i;
float aver,sum=0;
for(i=0; i<10; i++)
sum+=array[i];
aver=sum/10;
return(aver);
}
main( )
{ float score[10],aver;
int i;
for(i = 0; i < 10; i++)
scanf(“%f”,&score[i]);
aver = average(score);
printf("%f\n",aver);
}
(1) 实参是数组名
(2) 形参是指针变量可以写成数组形式可以不指定长度
float array[10]
例 8.8 求平均分
float array[ ]
float average( float *array)
{ int i;
float aver,sum=0;
for(i=0; i<10; i++)
sum+=array[i];
aver=sum/10;
return(aver);
}
main( )
{ float score[10],aver;
int i;
for(i = 0; i < 10; i++)
scanf(“%f”,&score[i])
aver = average(score);
printf("%f\n",aver);
}
score score[0]
score[9]
array
*(array+i)
(3) 若在函数中只处理部分数组元素,用参数指定个数
float average(float *array,int n)
{ int i;
float aver,sum=0;
for(i=0; i<n; i++)
sum += array[i];
aver=sum/n;
return(aver);
}
main()
{ float score[20],aver;
int i;
for(i = 0; i < 20; i++)
scanf(“%f”,&score[i]);
aver = average(score,20);
printf("%f\n",aver);
}
( 4) 数组名做为函数的参数,在函数调用时,将实参数组首元素的地址传给形参(指针变量),因此,形参也指向实参数组的首元素。如果改变形参所指向单元的值,就是改变实参数组首元素的值。
或:形参数组和实参数组共用同一段存贮空间,如果形参数组中元素的值发生变化,实参数组中元素的值也同时发生变化。
score score[0]
score[9]
array
例 8.9 冒泡法排序
9 8 8 8 8 8 5 4 4 0
8 9 5 5 5 5 4 5 0 4
5 5 9 4 4 4 6 0 5
4 4 4 9 6 6 0 6
6 6 6 6 9 0 8
0 0 0 0 0 9
相邻两个数比较,小的调到前面
i=1
i=2
i=3
i=4
i=5
a[j]>a[j+1]
j=0 to 4
j=0 to 3
j=0 to 2
j=0 to 6-1-i
9 8 8 8 8 8 5 4 4 0
8 9 5 5 5 5 4 5 0 4
5 5 9 4 4 4 6 0 5
4 4 4 9 6 6 0 6
6 6 6 6 9 0 8
0 0 0 0 0 9
9 8 5 4 6 0
i=1
j=0,8 9 5 4 6 0
j=1,8 5 9 4 6 0
j=2,8 5 4 9 6 0
j=3,8 5 4 6 9 0
j=4,8 5 4 6 0 9
main( )
{ int i,j,n,t,a[10];
n=6;
for(i=0; i<n; i++)
scanf("%d",&a[i]);
for(i=1; i<n; i++)
for(j=0; j < n-i; j++)
if(a[j] > a[j+1]) {
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
main()
{
int i,a[10]; ;
for(i=0; i<10; i++)
scanf("%d",&a[i]);
sort(a,10);
for(i=0; i<10; i++)
printf("%d ",a[i]);
printf("\n");
}
void sort(int *array,int n)
{
int i,j,t;
for(i=1; i<n; i++)
for(j=0; j<n-i; j++)
if(array[j]>array[j+1]){
t = array[j];
array[j] = array[j+1];
array[j+1] = t;
}
}
8.3 指针 和字符串
8.3.1 常用的字符串处理函数
8.3.2 字符串的指针表示
8.3.3 字符数组和字符指针
8.3.1 常用的字符串处理函数
1、使用 printf函数和 scanf函数输入输出字符串用 %s格式,将字符串一次性输入输出
static char str[20]=“Hello”;
⑴ 输出
printf("%s","Hello");
printf("%s",str);
注意:遇到 ‘ \0?,输出结束
for(i=0;str[i]!=?\0?;i++)
putchar(str[i]);
字符数组名输出:
Hello
Hello
⑵ 输入 scanf("%s",str);
注意:
① 输入参数使用数组名,不加地址符。
② 遇到回车或空格,输入结束,并自动在末尾加‘ \0?。
H o w \0
输入 How are you?
str中,
while((str[i]=getchar( ))!=) i++;
s[i]=?\0?;
③ 输入多个用空格分隔的字符串
char s1[20],s2[20],s3[20];
scanf("%s%s%s",s1,s2,s3);
s1,H o w \0
a r e \0
Y o u? \0
s2:
s3:
字符串可以一次性输入输出一般的字符数组只能逐个字符输入输出输入 How are you?
2、字符串输出函数 puts
static char str[20]=“hello”;
puts(str); 输出,Hello
puts(“World!”); 输出,World!
输出,Hello
World!
puts(str)与 printf(“%s”,str)的区别:
puts(str);,====,printf("%s\n",str);
自动 将结束符 ‘ \0? 转换成 '\n'
puts(“Hello”);
puts(“World!”);
输出,HelloWorld!printf(“%s”,“Hello”); printf(“%s”,“World!”);
static char str[20];
gets(str);
字符数组名
3、字符串输入函数 gets
△ 输入遇空格不结束,只有遇回车才结束。
gets(str);
输入,hello!
str中,hello!\0
gets(str) 与 scanf(“%s”,str) 的区别:
遇到回车或空格,输入结束例,gets(str);
输入,How are you?
Str,How are you?\0
scanf(“%s”,str);
输入,How are you?
Str,How\0
遇回车,输入结束
strcpy(str1,str2);
将字符串 str2 复制到 str1 中
static char str1[20];
static char str2[20] =,happy”;
4、字符串复制函数 strcpy
h a p p y \0
\0
strcpy(str1,str2); h a p p y \0str1中
strcpy(str1,,world”); str1中,world\0
# include,stdio.h”
# include,string.h”
main( )
{
char str1[20],str2[20];
gets(str2);
strcpy(str1,str2);
puts(str1);
}
输入,1234
输出,1234
strcat(str1,str2);
连接两个字符串 str1和 str2,并将结果放入 str1
中。
5、字符串连接函数 strcat
# include,stdio.h”
# include,string.h”
main( )
{
char str1[80],str2[20];
gets(str1);
gets(str2);
strcat(str1,str2);
puts(str1);
}
输入,Let us
go,
输出,Let us go.
str1中,Let us \0
str2中,go.\0
str1中,Let us go.\0
strcmp(str1,str2)
比较 两个字符串 str1和 str2的大小。
规则:按字典序 (ASCII码序 )
如果 str1 和 str2 相等,函数值是 0;
如果 str1 大于 str2,函数值是正整数;
如果 str1 小于 str2,函数值是负整数;
6,字符串比较函数 strcmp
如果 str1 和 str2 相等,函数值是 0;
如果 str1 大于 str2,函数值是正整数;
如果 str1 小于 str2,函数值是负整数;
static char s1[20] =,china”;
strcmp(“China”,“China,)
strcmp(s1,“china”)
正整数负整数
0
strcmp(s1,“China,)
# include,stdio.h”
# include,string.h”
main( )
{ int res;
char s1[20],s2[20];
gets(s1);
gets(s2);
res = strcmp(s1,s2);
printf(“%d”,res);
}
输入,1234
5
输出,-4
利用字符串比较函数比较字符串的大小
strcmp(str1,str2);
为什么定义这样的函数?
因为 str1 > str2
str1 <,hello”
str1 == str2
是非法的。
strcmp(str1,str2) > 0
strcmp(str1,“hello”) <0
strcmp(str1,str2)==0
strlen(str)
计算字符串的有效长度,不包括‘ \0?。
static char str[20]=“How are you?”
strlen(“hello”) 的值是:
strlen(str) 的值是:
7,字符串长度函数 strlen
5
12
函数 功能 头文件
puts(str) 输出字符串 stdio.h
gets(str) 输入字符串(回车间隔)
strcpy(s1,s2) s2 ==> s1
strcat(s1,s2) s1 + s2==>s1
strcmp(s1,s2) 若 s1 == s2,函数值为 0
若 s1 > s2,函数值 >0 string.h
若 s1 < s2,函数值 <0
strlen(str) 计算字符串的有效长度,
不包括‘ \0?
字符串处理函数小结
8.3.2 字符串的指针表示
1、用字符数组表示字符串
static char sa[ ]=“This is a string.”;
printf(“%s”,sa);
printf(“%s”,“Hello”);
sa[0]
sa[1]
sa[i]
sa
2、用字符指针表示字符串字符串是一个指针常量它的值就是该字符串的首地址由于字符串是一个指针常量定义一个字符指针,接收字符串指针常量
char *sp= "This is a string.";
printf("%s",sp);
8.3.2 字符串的指针表示
static char sa[ ]=“This is a string.”;
printf(“%s”,sa);
printf(“%s”,“Hello”);
1、使用字符指针进行字符串操作实现字符串复制函数 strcpy(s1,s2)
8.3.3 字符数组和字符指针
void strcpy(char s1[ ],char s2[ ])
{ int i;
for( i=0; s2[i]!='\0'; i++)
s1[i] = s2[i];
s1[i] = '\0';
} void strcpy(char s1[ ],char s2[ ]){ int i = 0;
while (s1[i] = s2[i]) i++;
}
用字符指针实现字符串复制函数 strcpy(s1,s2)
void strcpy(char s1[ ],char s2[ ])
{ int i = 0;
while (s1[i] = s2[i]) i++;
}
void strcpy(char *s1,char *s2)
{
while ( *s1= *s2){
s1++; s2++;
}
}
void strcpy(char *s1,char *s2)
{
while ( *s1++ = *s2++);
}
数组:改变下标指针:直接改变指针实现字符串长度函数 strlen(str)
int strlen(char str[ ])
{ int i=0;
while(str[i] != '\0?)
i++;
return i;
}
int strlen(char *str)
{ char * t=str;
while(*str!= '\0?)
str++;
return str-t;
}
实现字符串比较函数 strcmp(s1,s2)
int strcmp(char s1[ ],char s2[ ])
{ int i;
for( i=0; s1[i] != '\0'; i++)
if(s1[i] != s2[i]) break;
return s1[i]-s2[i];
}
strcmp(char *s1,char *s2)
{
for(; *s1 != '\0'; ++s1,++s2)
if(*s1 != *s2) break;
return(*s1 - *s2);
}
static char sa[ ]=“This is a string.”;
字符数组 sa由若干元素组成的,每个元素放一个字符,有确定的地址。
char * sp=“This is a string.”;
字符指针是一个接收字符串首地址的变量,不能将字符串放到字符指针变量中去。
在对指针赋值前,它的值是不确定的。
2、字符指针和字符数组的区别
static char sa[ ]=“This is a string.”;
char * sp=“This is a string.”;
static char sa[80];
char * sp;
数组,指针常量,有确定的地址指针,变量
strcpy(sa,“This is a string.”)
sa =,This is a string.”;
sp =,This is a string.”;
# include "stdio.h"
main( )
{ static char sa[ ]=“string”; /*设 sa的值 2000 */
char *sp ; /*设 sp的值 1fff */
printf("\n sa=%x,sp=%x\n",sa,sp);
sp = sa;
printf("sa=%x,sp=%x\n",sa,sp);
printf("%s,",sa);
printf("%s\n",sp);
}
输出,2000,1fff
2000,2000
string,string
例 8.10
# include "stdio.h"
main( )
{ char sa[80]; /*设 sa的值 2000 */
char *sp=“This is a string”; /*设 sp的值 1fff */
printf("\nsa=%x,sp=%x\n",sa,sp);
strcpy(sa,sp);
printf("sa=%x,sp=%x\n",sa,sp);
printf("%s",sp);
printf("%s\n",sp);
}
输出,2000,1fff
2000,1fff
string,string
指针变量必须先定义,后使用 。
例如,char *p;
scanf("%s",p);
可能出现难以预料的结果而 char *s,str[20];
s = str;
scanf("%s",s);
是正确的,
8.4 指针 数组和二级指针
8.4.1 指针数组
8.4.2 二级指针
8.4.3 指针数组和字符串
int i;
int a[10];
a是一个数组,它有 10个元素,
每个元素的类型都是整型。
int *p;
int *pa[10];
pa是一个数组,它有 10个元素,
每个元素的类型都是整型指针。
8.4.1 指针数组
int a[10];
a[0]
a[9]
a[i]
a
int *pa[10];
pa[0]
pa[9]
pa[i]
pa
int i,j,k,m;
int *pa[4];
pa[0]=&i;
pa[1]=&j;
pa[2]=&k;
pa[3]=&m;
pa[0]pa
pa[1]
pa[2]
pa[3]
i
j
k
m
*pa[0]
*pa[1]
*pa[2]
*pa[3]
int i=1,j=2,k=3,m=4;
int *pa[4]={&i,&j,&k,&m};
pa[0]pa
pa[1]
pa[2]
pa[3]
i
j
k
m
*pa[0]
*pa[1]
*pa[2]
*pa[3]
1
2
3
4
for( n=0; n<4; n++)
printf(“%x”,pa[n]);
for( n=0; n<4; n++)
printf(“%d”,*pa[n]);
int i=1,j=2,k=3,m=4;
int *pa[4]={&i,&j,&k,&m};
for( pp=pa; pp<pa+4; pp++)
printf(“%x”,*pp);
pp,
*pp
**pp
pa[0]pa
pa[1]
pa[2]
pa[3]
i
j
k
m
*pa[0]
*pa[1]
*pa[2]
*pa[3]
1
2
3
4
for( pp=pa; pp<pa+4; pp++)
printf(“%x”,**pp);
int i=1,j=2,k=3,m=4;
int *pa[4]={&i,&j,&k,&m};
如何定义 pp *pp **pp
pp,pa[0]pa
pa[1]
pa[2]
pa[3]
i
j
k
m
*pa[0]
*pa[1]
*pa[2]
*pa[3]
1
2
3
4
int **pp;
8.4.2 二级指针 (指向指针的指针 )
main()
{ int a = 10;
int *p = &a,**pp = &p;
printf("a=%d,*p=%d,**pp=%d\n",a,*p,**pp);
*p = 20;
printf("a=%d,*p=%d,**pp=%d\n",a,*p,**pp);
**pp = 30;
printf("a=%d,*p=%d,**pp=%d\n",a,*p,**pp);
}
&a
p a
10&p
pp
*p
*pp&&a **pp
输出,a=10,*p=10,**pp=10
a=20,*p=20,**pp=20
a=30,*p=30,**pp=30
main()
{ int a = 10,b = 80;
int *p = &a,**pp = &p;
printf("a=%d,b=%d,*p=%d,**pp=%d\n",a,b,*p,**pp);
p = &b;
printf("a=%d,b=%d,*p=%d,**pp=%d\n",a,b,*p,**pp);
}
&a
p a
10&p
pp
*p
*pp&&a **pp
输出,a=10,b=80,*p=10,**pp=10
a=10,b=80,*p=80,**pp=80
&b
&&b b
80
**pp
*p
char *name[4]={“Wang”,“Li”,“Zhao”,“Jin”};
8.4.3 指针数组和字符串
name[0]name,Wang”
name[1],Li”
name[2],Zhao”
name[3],Jin”
printf(“%s\n”,name[0]);
printf(“%c”,*name[0]);
输出:
Wang
W
char *name[4]={“Wang”,“Li”,“Zhao”,“Jin”};
name[0]name,Wang”
name[1],Li”
name[2],Zhao”
name[3],Jin”
输出:
Wang Li Zhao Jin
for( i=0; i<4; i++)
printf(“%s,,name[i]);
for( i=0; i<4; i++)
printf(“%c,,*name[i]);
输出:
W L Z J
输入月,输出相应的英文名称。
#include <stdio.h>
main( )
{ int month;
scanf("%d",&month);
if (month>=1 && month<=12)
prnname(month);
}
例 8.11
prnname(int m)
{ char *name[ ]={"January","February","March",
"April","May","June","July","August","September",
"October","November","December"};
printf("%3d,%s\n",m,name[m-1]);
}
name[0]name,January”
name[1],February”
name[11],December”
char *name[4]={“Wang”,“Li”,“Zhao”,“Jin”};
char ** pp = name;
printf(“%s\n”,*pp);
printf(“%c”,**pp);
name[0]name,Wang”
name[1],Li”
name[2],Zhao”
name[3],Jin”
*pp
pp
输出:
Wang
W
char *name[4]={“Wang”,“Li”,“Zhao”,“Jin”};
char ** pp = name;
printf(“%s\n”,*pp);
输出,Wang
name[0]name,Wang”
name[1],Li”
name[2],Zhao”
name[3],Jin”
*pp
pp
pp = pp + 2;
printf(“%s\n”,*pp);
printf(“%c”,**pp);
Zhao
Z
char *name[4]={“Wang”,“Li”,“Zhao”,“Jin”};
char ** pp;
for(pp=name;pp<name+4; pp++)
printf(“%s,,*pp); 输出:
Wang Li Zhao Jin
name[0]name,Wang”
name[1],Li”
name[2],Zhao”
name[3],Jin”
*pp
pp
char *name[4]={“Wang”,“Li”,“Zhao”,“Jin”};
char ** pp;
for(pp=name;pp<name+4; pp++)
printf(“%c,,**pp);
name[0]name,Wang”
name[1],Li”
name[2],Zhao”
name[3],Jin”
*pp
pp
输出:
W L Z J
char *name[4]={“Wang”,“Li”,“Zhao”,“Jin”};
char ** pp;
for(pp=name;pp<name+4; pp++)
printf(“%s,,*pp+1); 输出:
ang i hao in
name[0]name,Wang”
name[1],Li”
name[2],Zhao”
name[3],Jin”
*pp
pp
8.5 指针 和函数指针作为函数的返回值函数 match 在一个字符串 中寻找某个字符,
如找到,返回第一次找到的该字符在字符串的位置;否则,返回空指针 NULL。
char *match(char c,char *s)
{ while(*s != '\0')
if(*s == c) return(s); /* 返回指针 */
else s++;
return(0);
}
#include <stdio.h>
main( )
{ char *cp="ABCDEFGHIJK";
printf("%s\n",match(?B',cp));
printf("%s\n",match(?H',cp));
printf("%s\n",match(?a',cp));
}
输出,BCDEFGHIJK
HIJK
字符串复制函数 strcpy(s1,s2),返回 s1
char *strcpy(char *s1,char *s2)
{ char *ss=s1;
while ( *s1++ = *s2++);
return ss;
}
void strcpy(char *s1,char *s2)
{
while ( *s1++ = *s2++);
}