内容正文:
第 8 章 指针
2024年8月11日
内容概述
1.指针变量的概念、特点、定义和使用方法。
2.数组与指针的关系,包括一维数组和指针、字符串与指针等。
3.指针变量作函数参数、指向数组的指针作函数的参数。
2024年8月11日
教学目标
1.掌握指针和指针变量的概念,了解指针变量的特点以及直接访问数据和间接访问数据的原理。
2.掌握指针变量的定义、赋值方法及指针运算符的使用,熟练运用指针访问简单变量 。
3.熟悉指针和一维数组的关系,掌握指向一维数组的指针变量的定义方法,熟练使用指针变量访问一维数组元素。
4. 了解指针与字符串的关系,能熟练使用指针处理字符串。
5.熟练掌握用指针变量作函数的参数时函数的定义和调用方法、数组名作函数的参数用法。
2024年8月11日
C语言中,变量是有类型的,而且占据一定长度的内存单元。
通过前面的学习,我们已知道:
例如:
char ch; 变量ch占用1个字节的存储单元
int n; 变量n占用4个字节的存储单元
float x; 变量x占用4个字节的存储单元
double f; 变量f占用8个字节的存储单元
2024年8月11日
既然变量占据一定的内存空间,那么每一个变量都对应一个内存地址,这个地址为无符号整数,它不同于一般的整数。
问题: 能否对地址运算?
能否用一个变量保存地址?
2024年8月11日
8.5 数组名作函数的参数
1、数组元素作函数的参数。
值传递方式。
2、数组名作为函数的参数
实参与形参操作的是内存中的同一段地址单元,这样在被调用函数中对数组元素的内容的改变将会反映到调用函数中。(即地址传递或双向传递)
2024年8月11日
3、数组作函数的参数时,实参与形参还可用指针的形式给出:用数组名与数组的指针组合形式可以是:
实参
数组名
数组名
指针
指针
形参
数组名
指针
数组名
指针
2024年8月11日
【例8.7】编写函数,实现将数组a中的n个整数逆序存放。
定义函数“void inv(int x[],int n)”实现将数组x中的n个元素逆序存放。在主函数中定义数组a,并以数组a做实参调用函数inv()。在进行函数调用时,数组名a所代表的数组a的首地址传递给形参指针x,使x指向主函数中数组a所在的存储区,从而实现了将数组a中的n个整数按相反的顺序存放的目的。
2024年8月11日
void inv(int x[], int n)
{
int t,i,j,m=(n-1)/2;
for(i=0;i<=m;i++)
{
j=n-1-i;
t=x[i]; x[i]=x[j]; x[j]=t;
}
}
main()
{
int i,a[10]={8,7,9,1,0,6,7,3,4,2};
inv(a,10);
printf("The array has been reverted:
");
for(i=0;i<10;i++)
printf("%d,",a[i]);
printf("
");
}
2024年8月11日
对inv()函数,可以用指针实现如下:
void inv(int *x, int n)
{
int t,*i,*j,*p,m=(n-1)/2;
i=x; j=x+n-1; p=x+m;
for(;i<=p;i++,j--)
{ t=*i; *i=*j; *j=t; }
}
2024年8月11日
课堂练习1: 下面程序的输出结果是:
#define MAX 3
int a[MAX];
fun1()
{
int k,t=0;
for(k=0;k<MAX;k++,t++) a[k]=t+t;
}
fun2(int b[])
{ int k;
for(k=0;k<MAX;k++)
printf(“%d”,*(b+k));
}
main()
{
fun1();
fun2(a);
printf(“
”);
}
运行结果为:
0 2 4
2024年8月11日
课堂练习2:分析以下程序的输出结果。
float sort(int data[],int n)
{
int i,j,t;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
if(data[i]<data[j])
{t=data[i];data[i]=data[j];data[j]=t;}
}
main()
{
int array[5]={2,8,7,5,9};
int i;
sort(array,3);
for(i=0;i<5;i++)
printf(“%d”,array[i]);printf(“
”);
}
运行结果为:
87259
2024年8月11日
课堂练习3 :分析下列程序的执行结果.
#include <stdio.h>
void fun(int *s)
{
static int j=0;
do{
s[j]+=s[j+1];
} while(++j<2);
}
main()
{
int k,a[10]={1,2,3,4,5};
for(k=1;k<3;k++)
fun(a);
for(k=0;k<5;k++)
printf(“%d”,a[k]);
}
运行结果为:
35745
2024年8月11日
课堂练习4 : (程序运行结果)
#include<stdio.h>
int n=3;
int fun(int b[3][3]); /*声明函数*/
main()
{ int a[3][3]={1,-2,-5,-1,2,5,-4,4,3},s;
s=fun(a);
printf("s=%d
",s);
}
int fun(int b[3][3])
{ int i,j,sum=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(b[i][j]<i+j) sum=sum+b[i][j];
return(sum);
}
结果:-9
2024年8月11日
课堂练习5 :分析下列程序的执行结果.
#include<stdio.h>
int n=3;
int fun(int b[]); /*声明函数*/
main()
{ int a[9]={1,-2,-5,-1},s;
s=fun(a);
printf("s=%d
",s);
}
int fun(int b[])
{ int i,j,sum=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(b[i]<i+j) sum=sum+b[i];
return(sum);
}
结果:-30
2024年8月11日
8.6 字符串与指针
在C语言中,字符串是以'\0'作为结束标志的字符数组,它有以下几种表示方法:
(1)char str1[]="I am a student! ";
定义一个字符数组str1,其中存储的是字符串本身
(2)char *str2="I am a student! ";
定义一个字符指针变量str2,其中存储字符串的首地址
(3)char *str3=(char*)malloc(sizeof(char)*20);
定义一个字符指针变量str3,指向一块动态申请的存储空间
(4)strcpy(str3,str2);
将str2所指向的字符串常量复制到str3所指向的存储空间中
2024年8月11日
【例8.8】将字符串中所有字符'a'替换成字符'b'。
#include "stdio.h"
void main()
{ char str[20]="I am a student!",*p;
for(p=str;*p;p++)
/* 条件*p等价于*p!= '\0' */
if(*p=='a')
*p='b';
puts(str);
}
2024年8月11日
【例8.9】编写程序把字符串a复制到字符串b(不用strcpy函数)。
#include "stdio.h"
main()
{
char a[]="I am a teacher! ";
char b[20];
int i=0;
while(b[i]=a[i])
i++;
printf("string a is: %s
", a);
printf("string b is: %s
",b);
}
2024年8月11日
【例8.10】用函数调用方式实现字符串的复制。
#include "stdio.h"
void string_copy(char *from, char *to)
{ int i=0;
for(;(*(to+i)=*(from+i))!= "\0";i++);
/*循环体为空语句*/
}
main()
{ char str1[20]= "I am a teacher.";
char str2[20];
string_copy(str1, str2); /*数组名作为实参*/
printf("%s
", str2);
}
2024年8月11日
要点:
1、字符串指针可以用来描述一个字符串。
方法: char *str=“I am a student.”;
2、意义
不是将字符串的内容赋值给指针变量,而是将其起始地址赋给它。
char *str;
str=“I am a student.”;
2024年8月11日
3、应用:
利用字符串的指针变量对字符串进行输入与输出。
puts(),gets()
scanf(),printf()的%s输出格式。
运行结果为:
ABCDE
BCDE
CDE
DE
E
练习:分析下面的程序
main()
{
char arr[]=“ABCDE”;
char *ptr;
for(ptr=arr;ptr<arr+5;ptr++)
printf(“%s
”,ptr);
}
2024年8月11日
练习 :有以下的程序,输出结果为:
main()
{
char *p1=“programming”,*p2=“language”;
int i;
for(i=0;i<7;i++)
if(*(p1+i)==*(p2+i))
printf(“%c”,*(p1+i));
}
输出结果:
ga
2024年8月11日
3 字符指针与字符数组的区别
字符数组由若干个元素组成,每个元素存放一个字符,而字符指针存放的地址(当处理字符串时存放的是字符串的地址);
赋初值方式不同;
char a[]=“I am a student.”;
char *str=“I love China.”;
2024年8月11日
赋值方式不同;
1) 对于字符数组赋值不能使用以下的方法:
char str[10];
str=“book”;
2) 对于字符类型的指针变量可以使用以下的方法:
char *str;
str=“This is a book.”;
2024年8月11日
字符指针变量在使用之前必须初始化,即使其指向一个具体的存储单元。如:
char str[];
scanf(“%s”,str);是正确的
而 char *str;
scanf(“%s”,str);将是错误的。
指向字符类型的指针变量可以用指针的形式表示,也可以用下标的形式表示。
2024年8月11日
main( )
{
char *s="12134211";
int v[4]={0,0,0,0},k,i;
for(k=0;s[k];k++)
{
switch(s[k])
{ case '1': i=0; break;
case '2': i=1; break;
case '3': i=2; break;
case '4': i=3;
}
v[i]++;
}
for(k=0;k<4;k++)
printf("%d",v[k]);
}
运行结果:
4211
课堂练习1:以下程序的输出结果是_______
2024年8月11日
课堂练习2:分析以下的程序
main()
{
int a[ ]={1,2,3,4,5,6,7,8,9,0},*p;
p=a;
printf("%d
",*p+9);
}
运行结果:
10
2024年8月11日
课堂练习3:分析以下的程序
void fun(int *x, int *y)
{
printf("%d %d", *x, *y);
*x=3;
*y=4;
}
main()
{
int x=1,y=2;
fun(&y,&x);
printf(" %d %d",x, y);
}
运行结果:
2 1 4 3
2024年8月11日
void fun(char *a,char *b)
{ a=b; (*a)++; }
void main()
{ char c1='A',c2='a',*p1,*p2;
p1=&c1; p2=&c2;
fun(p1,p2);
printf("%c%c
",c1,c2);
}
运行结果:
Ab
课堂练习4:以下程序的输出结果是_______
2024年8月11日
课堂练习5:以下程序的功能是:将无符号八进制数字构成的字符串转换为十进制整数。例如,输入的字符串为:125,则输出十进制整数85。请填空。
main()
{
char *p, s[6];
int n;
p=s;
gets(p);
n= ;
while( !='\0')
n=n*8+*p-'0';
printf("%d
",n);
}
*p-'0'
*++p
2024年8月11日
编程序,判断输入的字符串是不是”回文”(按顺序读和倒顺序读都一样的字符串称为“回文”,如abcdcba)。
要求:用指针变量输入字符串,并用地址运算判断字符串是否“回文”。
编程练习1:
2024年8月11日
#include<stdio.h>
#include<string.h>
main()
{ char ch[80],*p=ch,*q;
gets(p); /*用指针变量输入字符串的首地址*/
q=p+strlen(p)-1; /*将字符串最后一个字符的地址赋给q*/
while(p<q) /*判断p,q地址满足条件执行循环*/
{
if(*p==*q) {p++;q--;}
else break ;
}
if(p<q)
{ p=ch ; printf(“%s不是回文
”,p) ; }
else
{ p=ch; printf(“%s是回文
”, p) ; }
}
2024年8月11日
编程练习2:
编程序,删除从键盘输入的字符串中的所有数字字符(用宏命令定义数组长度)。
#include<stdio.h>
#define N 30
void fun(char a[],char b[]);
main()
{ char a[N],b[N];
printf("Input astring:");
gets(a) ; /*scanf(“%s”,a); 不能接收空格*/
fun(a,b);
printf("%s
",b);
}
2024年8月11日
void fun(char a[],char b[])
{
int i=0,j=0 ;
while(a[i]!='\0')
{
if(a[i]<'\0'||a[i]>'9')
{ b[j]=a[i]; j++; }
i++;
}
b[j]='\0';
}
$$