第七讲指针本节学习目标
指针与指针变量
指针的声明与使用
指针与数组间的关系
动态分配内存课前复习
一维数组的定义与使用
二维数组的定义与使用
字符数组的使用数据的存储机制
内存地址
– —内存中存储单元的编号。
变量地址
– —系统标识变量在内存中的起始位置。
数据的存储机制(续)
直接访问
– #include <stdio.h>
– void main()
– {
– int a,b,sum;
– printf("请输入 a和 b的值:
");
– scanf("%d,%d",&a,&b);
– sum=a+b;
– printf("sum=%d\n",sum);
– }
间接访问
– #include <stdio.h>
– void main()
– {
– int a,b,sum=0;
– int *p_1,*p_2;
– printf("请输入 a和 b的值:
");
– scanf("%d,%d",&a,&b);
– p_1=&a;p_2=&b;
– sum=*p_1+*p_2;
– printf("sum=%d\n",sum);
– }
指针的功能
方便一个函数向另一个函数的过渡。
能通过指针的移动来改变指针所指向的数据,不需要去移动变量或数组。
可以实现动态内存的更新。
指针与指针变量
什么是指针?
– 变量的内存地址。
指针变量
用来存放变量地址的变量。
56
a 变量名
1000
( 内存地址 )
变量值
1000
b
指针指针变量指针声明
格式数据类型 *指针变量名;
声明注意事项
―*‖表示声明的指针变量,不是代表指针运算符。
,*”前必须指定数据类型(基类型),
其主要功能是指指针所指向对象的数据类型。
基类型:指针所指向的数据类型。决定了指针每次移动的步长。
指针的赋值与引用
指针运算符
– &——求址运算符( …… 的地址)
– *——指针运算符( …… 地址中的值)
范例
int a = 10;
int *p;
p = &a; a p10
10 100
int a=10,int *p
p=&a
地址地址 100 104
100 104
指针赋值 2-1
通过 & 运算符为指针赋值
ptr_var = &var;
通过另一个指向相同类型数据项的指针变量对指针进行赋值
ptr_var2 = ptr_var;
指针赋值 2-2
通过指针为变量赋值
*ptr_var = 10;
如果 ptr_var指向 var,则把 10赋给 var
课堂练习
写出下列计算结果
– int a=5;/*a的内存地址为 3000*/
– int *p;
– p=&a;
(1):p; (2)&p (3)*p
(4):a (5)&a
课堂练习
写出下列计算结果
int num1=2,num2,*pnt;
pnt=&num1;
num2=*pnt;
(1)num1 (2) num2 (3)*pnt
例 题输入两个数,按从大到小的顺序排列。
#include <stdio.h>
void main()
{
int a,b;
int *p_1,*p_2,*max;
p_1=&a;p_2=&b;
printf("请输入 a和 b的数,");
scanf("%d,%d",&a,&b);
if (a<b)
{
max=p_1;p_1=p_2;p_2=max;
}
printf("%d,%d\n",*p_1,*p_2);
}
数组指针与数组的指针变量
什么是数组指针?
– 数组在内存中的地址。
数组的指针变量
– 存放数组元素地址的变量。
指针与一维数组 3-1
数组元素的地址可以用两种方式表示
– 在数组元素前面加,&”符号
&ary[2]
– 数组名 + 下标
ary + 2
指针与一维数组 3-2
#include <stdio.h>
void main()
{
static int ary[10] = {1,2,3,4,5,6,7,8,9,10};
int i;
for (i = 0; i < 10; i ++)
{
printf(“\ni=%d,ary月 [i]=%d,*(ary+i)=%d",i,ary[i],*(ary + i));
printf("&ary[i]= %X,ary+i=%X",&ary[i],ary+i);
}
}
值地址指针与一维数组 3-3
演示:
执行程序,观察并分析输出结果使用指针引用数组元素
数组的方法
– #include <stdio.h>
– void main()
– {
– int a[5]={6,7,8,9,10};
– int i;
– for (i=0;i<5;i++)
– {

printf("a[%d]:%d\n",i,a[i]);
– }
– }
指针的方法
– #include <stdio.h>
– void main()
– {
– int a[5]={6,7,8,9,10};
– int *p;
– for (p=a;p<a+5;p++)
– {
– printf("%d\n",*p);
– }
– }
使用指针变量的注意事项
只能进行加法和减法运算
int var,*ptr_var;
ptr_var = &var;
ptr_var ++;
假定 var存储在地址 1000中,因为整数的长度是 2
个字节,ptr_var的值将是 1002
指针运算 2-2
指针递增时,将指向其类型的下一个元素的内存位置,反之亦然操作 意义
++ptr_var或 ptr_var++ 指向 var 后面的下一个整数
--ptr_var或 ptr_var-- 指向 var 前面的整数
ptr_var + i 指向 var 后面的第 i 个整数
ptr_var - i 指向 var 前面的第 i 个整数
++(*ptr_var)或
(*ptr_var)++ 将 var 的值加 1
*(ptr_var++) 取出 var 后面的下一个整数的值课堂练习
1.若有定义,int x,*pb;则以下正确的赋值表达式是( )
A)pb=&x B) pb=x C)*pb=&x D)*pb=*x
2.若 p和 q已正确定义,并指向同一连续单元如下,请回答如下问题:
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7]
p^ q^
10 20 30 40 50 60 70 80
课堂练习
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7]
p^ q^
1.表达式 *p-*q 的值是___.
2.表达式 *++p 的值是__,指针 p是否移动 __.
3.表达式 --*q 的值是__,指针 q是否移动 ___.
4.表达式 *--q 的值是__,指针 q是否移动 ___.
5.表达式 ++*p 的值是__,指针 p是否移动 ___.
6.表达式 (*p)-- 的值是__,指针 p是否移动 ___.
7.表达式 *q-- 的值是__,指针 q是否移动 ____,*q的值是_.
10 20 30 40 50 60 70 80
注意事项
可以通过指针将一个数组元素赋给另一个数组元素,但不能将一个数组元素的地址赋给另一个数组元素。
Ary[2]=ary[3];//允许
&ary[2]=&ary[3];//不允许指针与字符串 2-1
#include <stdio.h>
void main()
{
char ary[10]="chinese";
char *p;
p=ary+2;
printf("%c",*p);
}
指针与字符串 2-2
#include <stdio.h>
#include <string.h>
void main ()
{
char a,str[81],*ptr;
printf("\nEnter a sentence,");
gets(str);//输入一个字符串
printf("\nEnter character to search for,");
a = getche();//输入要查找字符
ptr = strchr(str,a);
/* return pointer to char */
printf("\nString starts at address,%u",str);
printf("\nFirst occurrence of the character is at,%u",ptr);
printf(,\nPosition of first occurrence is,%d”,ptr-str);
}
指针运算
Strchr()函数:
计算指定字符在字符串中第一次出现的地址。
分配内存 2-1
malloc() 是最常用的函数之一
它允许从空闲内存池中分配内存
malloc() 的参数是代表所需字节数的整数分配内存 2-2
#include <stdio.h>
#include <malloc.h>
void main() {
int *p,n,i,j,temp;
printf("\n Enter number of elements in the array,");
scanf("%d",&n);
p=(int*)malloc(n*sizeof(int));
for(i=0;i<n;++i) {
printf("\n Enter element no,%d,",i+1);
scanf("%d",p+i);
}
for(i=0;i<n-1;++i)
for(j=i+1;j<n;++j)
if(*(p+i)>*(p+j)) {
temp=*(p+i);
*(p+i)=*(p+j);
*(p+j)=temp;
}
for(i=0;i<n;++i)
printf("%d\n",*(p+i));
}
分配内存排序
free()函数 3-1
使用 free() 函数释放不再需要的内存
void free(void *ptr);
ptr 必须是通过 malloc(),calloc()或 realloc()
分配的指针
free()函数 3-2
#include <stdio.h>
#include <stdlib.h>
int main() {
int number;
int *ptr;
int i;
printf("How many ints?");
scanf("%d",&number);
ptr = (int *) malloc
(number*sizeof(int));
if(ptr!=NULL)
{
for(i=0 ; i<number ; i++)
{
*(ptr+i) = i;
}
for(i=number ; i>0 ; i--)
{
printf("%d\n",*(ptr+(i-1)));
}
free(ptr);
return 0;
}
else
{
printf("\nMemory allocation
failed.\n");
return 1;
}
}
定义分配判断释放
free()函数 3-3
演示:
执行程序,观察并分析输出结果
calloc()函数 3-1
calloc()与 malloc()类似
主要的区别是存储在已分配的内存空间中的值默认为零
calloc()需要两个参数
– 要分配内存的变量的个数
– 每个变量的大小
void *calloc( size_t num,size_t size );
calloc()函数 3-2
#include <stdio.h>
#include <stdlib.h>
int main() {
float *calloc1,*calloc2;
int i;
calloc1 = (float *) calloc(3,sizeof(float));
calloc2 = (float *)calloc(3,sizeof(float));
if(calloc1!=NULL && calloc2!=NULL) {
for(i=0 ; i<3 ; i++) {
printf("\ncalloc1[%d] holds %05.5f ",i,calloc1[i]);
printf("\ncalloc2[%d] holds %05.5f ",i,*(calloc2+i));
}
free(calloc1);
free(calloc2);
return 0;
}
else {
printf("Not enough memory \n");
return 1;
}
}
定义分配判断释放
calloc()函数 3-3
演示:
执行程序,观察并分析输出结果
realloc()函数 3-1
为已经分配的内存重新分配空间并复制内容
realloc()函数有两个参数
– 已分配的内存地址
– 重新分配的字节数
void *realloc( void *ptr,size_t size );
realloc()函数 3-2
#include<stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
int i;
ptr = (int *)calloc(5,
sizeof(int *));
if(ptr!=NULL)
{
*ptr = 1;
*(ptr+1) = 2;
ptr[2] = 4;
ptr[3] = 8;
ptr[4] = 16;
ptr = (int *)realloc(ptr,
7*sizeof(int));
if(ptr!=NULL)
{
ptr[5] = 32;
ptr[6] = 64;
for(i=0;i<7;i++)
{
printf(“ptr[%d]:%d\n",i,
ptr[i]);
}
realloc(ptr,0); /* free(ptr);*/
return 0;
}
定义分配判断释放再分配
realloc()函数 3-3
演示:
执行程序,观察并分析输出结果总结
如何使用指针变量和指针运算符
指针赋值
指针运算
指针比较
指针与数组
内存分配