内容正文:
《C语言程序设计》
(天津大学出版社)
第7章 指针、函数和数组
7.1 变量的地址和指针
7.2 指针变量
7.3 一维数组和指针
7.4 一维数组和函数
7.5 二维数组和指针
7.6 二维数组和函数
7.7 字符串和指针
7.8 指向函数的指针
7.9 返回指针值的函数
7.10 指针数组和二级指针
7.1 变量的地址和指针
存储空间:存储空间(Storage Space)是一种逻辑存储结构,它对上层应用提供寻址空间和相应的逻辑存储单元(Logic Storage Unit),并提供操作集(Access Operations)用于存取存储单元中的数据;同时在内部具有表示存储空间的数据结构(Meta data)实现逻辑存储单元和下层存储空间地址的映射关系;具有访问下层存储空间的存取操作集,把上层对于逻辑存储单元的数据存取请求解析传递给下级存储空间。
C语言程序任何一个变量都必须占用一定的存储空间。变量的存储空间依变量的类型而决定。
7.1 变量的地址和指针
例7.1 不同类型变量的存储空间
#include <stdio.h>
main ()
{
int i;long l;char c;float f; double d;
printf ("int变量占用的存储空间为:%d
",sizeof (i));
printf ("long变量占用的存储空间为:%d
",sizeof (l));
printf ("char变量占用的存储空间为:%d
",sizeof (c));
printf ("float变量占用的存储空间为:%d
",sizeof (f));
printf ("double变量占用的存储空间为:%d
",sizeof (d));
printf ("
");
}
运行结果:
int变量占用的存储空间为:4
long变量占用的存储空间为:4
char变量占用的存储空间为:1
float变量占用的存储空间为:4
double变量占用的存储空间为:8
分析:
int型变量的存储空间为4。long型变量的存储空间为4,char型变量的存储空间为1,float型变量的存储空间为4,double型变量的存储空间为8。其中,单位为字节。
7.1 变量的地址和指针
问题:变量的存储空间的实际地址应该如何获取?
C语言中,我们采取&变量名的方法完成变量地址的获取。
采用&变量名的方法取得变量的地址也是一个值,该内存地址值就是实际占用多少存储空间
7.1 变量的地址和指针
例7.2 变量地址的存储空间
#include <stdio.h>
main ()
{
int i;long l;char c;float f; double d;
printf ("int变量占用的存储空间为:%d
",sizeof (&i));
printf ("long变量占用的存储空间为:%d
",sizeof (&l));
printf ("char变量占用的存储空间为:%d
",sizeof (&c));
printf ("float变量占用的存储空间为:%d
",sizeof (&f));
printf ("double变量占用的存储空间为:%d
",sizeof (&d));
printf ("
");
}
运行结果:
int变量占用的存储空间为:4
long变量占用的存储空间为:4
char变量占用的存储空间为:4
float变量占用的存储空间为:4
double变量占用的存储空间为:4
分析:
从上面的例子可以看到,基本数据类型变量在系统中使用4个字节来表示该变量的内存地址。那么考虑是否有有一种方式:直接通过地址来访问该变量,而无需使用该变量的名字?答案是肯定的,那就是指针变量。而变量的内存地址通常被称为:指针。
7.2 指针变量
7.2.1 指针变量的定义
7.2.2 怎样引用指针变量
7.2.3 指针变量作为函数参数
7.2.1 指针变量的定义
指针:就是某个变量的内存地址。如果有一种特殊变量能够存储各种类型变量的内存地址,则在使用当中通过改变这种特殊变量的值就可以达到变换不同内存地址的目的。那么当然有可能通过该特殊变量来访问对应的内存。
指针变量:定义为存储变量内存地址的一种特殊变量。
7.2.1 指针变量的定义
指针变量的声明方法比较简单,且任何一种类型的变量都可以声明指针变量。
格式: 类型 *指针变量名;
例7.3 指针的声明
int *p; //p被声明为整型变量的指针
char *pc; //pc被声明为字符变量的指针
long *pl; //pl被声明为长整型变量的指针
float *pf; //pf被声明为浮点型变量的指针
double *pd; //pd被声明为双精度浮点类型变量的指针
//也可以声明为无类型的指针:
void *pv; //pv被声明为任意类型变量的指针
7.2.1 指针变量的定义
既然指针是某
个内存的地址,
指针变量是一
种特殊变量,
指针的示意图
可以使用右边
的图来表达前
面的例子:
返回
7.2.2 怎样引用指针变量
指针是一种特殊类型的变量,任何一种类型的变量都可以把其所在的内存地址赋给指针变量。赋值的方法如下:
指针变量名 = &变量名;
7.2.2 怎样引用指针变量
例7.4 指针类型的赋值与占用的存储空间
#include <stdio.h>
main ()
{
int i,*pi;long l,*pl;char c,*pc;float f,*pf;double d,*pd;
pi = &i;pl = &l;pc = &c;pf = &f; pd = &d;
printf ("int变量的指针占用的存储空间为:%d
",sizeof (pi));
printf ("long变量的指针占用的存储空间为:%d
",sizeof (pl));
printf ("char变量的指针占用的存储空间为:%d
",sizeof (pc));
printf ("float变量的指针占用的存储空间为:%d
",sizeof (pf));
printf ("double变量的指针占用的存储空间为:%d
",sizeof (pd));
printf ("
");
}
运行结果:
int变量的指针占用的存储空间为:4
long变量的指针占用的存储空间为:4
char变量的指针占用的存储空间为:4
float变量的指针占用的存储空间为:4
double变量的指针占用的存储空间为:4
分析:
上例子可见,赋值给指针变量的方法很简单,只需要取得变量的地址就可以把该地址赋值给对应类型的指针变量了。
7.2.2 怎样引用指针变量
问题:那么如何使用该指针变量?使用指针变量的目的在于使用另外一条途径对变量进行操作。
指针变量的引用方法如下:
格式: *指针名 = 表达式;
请特别注意:
指针名 = &变量名;与 *指针名 = 表达式;两者之间的区别:
1、指针名 = &变量名;//这个语句表达了:把变量的地址存放到指针变量中。
2、*指针名 = 表达式;//这个语句表达了:将表达式的计算结果值存储到指针变量所存放的内存地址所代表的内存单元中去 。
7.2.2 怎样引用指针变量
例7.5 引用指针变量的例子
#include <stdio.h>
main ()
{
int i,*pi=&i;
long l,*pl=&l;
char c,*pc=&c;
float f,*pf=&f;
double d,*pd=&d;
i=1;
printf ("i变量的值为:%d
",i);
*pi = 10;
printf ("i变量的值改变为:%d,*pi的值为:%d
",i,*pi);
l=16;
printf ("l变量的值为:%ld
",l);
*pl = 10;
printf ("l变量的值改变为:%d,*pl的值为:%ld
",i,*pl);
c='a';
printf ("c变量的值为:%c
",c);
*pc = 'D';
printf ("c变量的值改变为:%c,*pc的值为:%c
",c,*pc);
f=1.5;
printf ("f变量的值为:%f
",f);
*pf = 55.5;
printf ("f变量的值改变为:%f,*pf的值为:%f
",f,*pf);
d=123.456;
printf ("d变量的值为:%lf
",d);
*pd = 654.321;
printf ("d变量的值改变为:%lf,*pd的值为:%lf
",f,*pd);
printf ("
");
}
运行结果:
i变量的值为:1
i变量的值改变为:10,*pi的值为:10
l变量的值为:16
l变量的值改变为:10,*pl的值为:10
c变量的值为:a
c变量的值改变为:D,*pc的值为:D
f变量的值为:1.500000
f变量的值改变为:55.500000,*pf的值为:55.500000
d变量的值为:123.456000
d变量的值改变为:55.500000,*pd的值为:654.321000
分析:
例子清楚地说明了指针变量是变量的别名,通过指针变量获得了变量的另外一种操作方式,给变量的赋值提供了另一种操作方法。但是,应该注意到,由于优先级与结合性等问题,指针的合理使用非常关键,看这样一个例子
7.2.2 怎样引用指针变量
例7.6 若定义语句:int year=2009,*p=&year;,以下不能使变量 year 中的值增至 2010 的语句是:(2011年9月全国计算机等级考试二级C试题选择题第25题)
A.*p+=1; B.(*p)++; C.++(*p); D.*p++;
分析:答案A.*p+=1;可理解为:*p=*p+1,即2009+1=2010。
答案B.(*p)++;语句同A答案只是明确了优先级为(*p)的内容自加一
答案C.++(*p);同答案B
答案D.*p++; 由于++的优先级高于*故此先做加法,即先把p的值增加一,这样做的结果是:指针变量p中保存的year变量地址被改变了(p变量的内容加一之后,保存的内容就已经不是year变量的地址了,具体是什么地址是不确定的),则*p的内容也就无法预知。
返回
7.2.3 指针变量作为函数参数
指针变量具有高度的灵活性,它可以作为函数的参数来使用。将指针作为函数的参数使用方法如下:
函数返回值 函数名 (…,类型名 *指针名,…)
也就是简单地将指针(地址)赋给函数作为函数的参数即可。特别需要注意的是:当函数的形参为指针,若实参为变量时提供的是变量的地址,需要使用:&变量名。同样,当函数的形参为指针,若实参为数组时,提供的是数组名(数组名就是数组的首地址),即:数组名。关于数组名就是数组的首地址问题在下一节中会详细介绍。这里首先来看指针变量做为函数的参数。
7.2.3 指针变量作为函数参数
例7.7 指针作为参数传递(2010年3月全国计算机等级考试二级C试题选择题第26题)
#include <stdio.h>
//定义了函数fun。其中参数c是一个指针变量,而d不是指针变量
void fun(char *c,int d)
{
*c=*c+1;
d=d+1;
printf ("%c,%c",*c,d);
}
main()
{
char b='a',a='A';
fun(&b,a);
printf ("%c,%c
",b,a);
}
程序运行后的输出结果是
A)b,B,b,A B)b,B,B,A
C)a,B,B,a D)a,B,a,B
谢谢观看
$$