您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 数据通信与网络 > 指针数组知识总结计算机二级C辅导
第六章指针一、变量的地址和指针(一)变量的地址1、内存地址:计算机的内存是以字节为单位的一片连续的存储空间,每一个字节都有一个编号,这个编号就称为地址。例如:一台计算机内存为512MB=512*1024KB=512*1024*1024B,即共有512*1024*1024个地址。(1)内存空间都是连续的,故地址编号也是连续的。(2)定义变量后自动分配相应的内存空间。例如:inta;自动分配4个字节的内存空间给变量a。(画图说明:1011、1012、1013、1014)(3)每个变量的地址是指所占存储单元的第一个字节的地址。例如:上例中变量a的地址为1011。2、直接存取方式:直接按变量的地址存取变量值的方式。例如:inta;a=5;为变量a分配内存空间,进而变量a有了对应的内存地址,将5赋值给变量a,即将5存入变量a对应的内存空间。看似对变量a赋值,实际上是对变量a对应的内存空间存放数值。3、关于地址的形象认识:打个比喻:内存好比就是一个公司的行政大楼,内存当中的每一个字节就好比是大楼中的每一个房间,每一字节内存都有编号,即内存地址,就好比是房间的门牌号。我们定义一个变量a就要为这个变量a分配内存空间,就好比是公司成立一个财务科就要为这个财务科分配房间。将5赋值给变量a就好比是要将一大摞钱送到财务科,实际上就是将钱送到财务科所在的那个房间,同理也就是将5存放到变量a对应的内存空间,而具体怎么由变量a找到其对应的内存空间,是由计算机完成的,因为a的内存空间的分配就是计算机完成的。就好比是我们要找财务科,如果不熟悉地方的话,就问公司内部人员,他会告诉你房间号,同理计算机就如同公司内部人员,它就会告诉5怎么找到变量a的内存空间,即a的地址。通过变量a对其内存空间进行存取数据的方式称为直接存取。(二)指针变量的定义1、间接存取方式:我们定义一种变量,这种变量是专门用来存放某种内存地址的。比如我们定义变量p,计算机就为它分配内存空间,就当然有地址(假如为9257)。将变量a的内存地址(1011)存放到变量p中,此时我们要访问变量a所代表的存储单元,我们可以先找到变量p的地址(9527),从中取出a的地址(1011),然后再去访问1011为首地址的存储单元。这种方式就称为“间接存取”方式。(1)一旦变量p存放了变量a的地址就称变量p指向变量a。此时变量p称为指针(地址)变量,它与变量a不同,它是用来存放指针(即地址)的变量。(2)任何类型的指针变量均占4Bytes。2、指针变量定义:类型名*指针变量名1,*指针变量名2,…;例:int*p,*q;(1)p、q为用户标识符,*为说明符,不可省略,否则就不是指针变量而为普通变量了。(2)int为类型名,说明p和q是两个指向整型变量的指针,即变量p和q只能存放int类型变量的地址。称int是指针变量p和q的“基类型”。(3)二级指针:类型名**指针变量名1,**指针变量名2,…;例:int**p;二级指针变量就是其中存放的是指针变量的地址。例如:定义一个int变量k,其内存空间为(2012、2013、2014、2015),再定义int*s;s的地址为9521,但是其指向2012,即其中存放的内容为2012,再定义二级指针:int**p;p地址为4567,它指向9521,即p对应的内存空间存放的是指针s的地址,即指针的地址,称为二级指针。(画图阐述)二、指针变量赋值及运算(一)指针变量赋值1、通过求地址运算符“&”给指针变量赋地址值:利用“&”运算符把一个变量的地址值赋给指针变量。例如:inta=10,*p,*q;p=&a;表示将a的地址赋给了p,我们就说p指向了变量a。(回忆scanf)(1)求地址运算符可用于变量(包括指针变量)和数组元素,但不可用于表达式、常量。因为表达式、常量无内存分配单元;(2)求地址运算符只能放在运算对象的左边;(3)&右边的运算对象的类型必须与被赋值的那个指针变量的基类型是严格相同的。(4)理解:把(int*)理解为一个类型,这样的话对于上例,若是p=a;则错了,因为a是int型的,而p为(int*),而在a右边加上&就可赋给p了,也就是说在int类型变量右边加上&则变为了(int*),同理float变量右边加上&则变为(float*)类型。那么在(int*)指针变量右边加上&则变为(int**)类型(二级指针)。而事实上,不存在(int*)和(int**)类型。2、通过其他指针变量获得地址值:类型相同的指针变量之间可以相互赋值,从而使两个指针变量指向同一地址。例如:int*p,*q,a;p=&a;q=p;p和q指向同一个变量。(强调:赋值号两边的指针变量的“基类型”必须相同。)3、通过标准函数获得地址值:通过C语言中的标准库函数的malloc和calloc函数动态分配内存中的存储单元,并把存储单元的起始地址付给指针变量,从而是指针变量指向某一连续的内存空间。(后续内容)4、给指针变量赋“空”值:含义是该指针变量不指向任何变量。格式:int*p;p=NULL;也可以是p=0或者p=’\0’;(NULL的ASCII值为0,’\0’也代表空值Page27)(1)此时指针p不是指向地址为0的存储单元,而是具有一个确定的值“空”;(2)不能通过一个空指针去访问一个存储单元。(二)间接访问运算符(引用内存单元)1、间接访问运算符:*2、含义:*p表示访问p所指向变量的值(p为指针变量)例:inta=8,b,*p;p=&a;b=*p;含义是把指针变量p所指向的变量a的值赋给变量b,此处*p意味着取指针变量所指向变量的内容。将指针变量所指向的变量a中存放的数据加1之后赋给变量b,以下语句是等价的:①b=a+1;②b=*p+1;③b=*(&a)+1;④b=*p+=1;⑤b=++*p;(1)间接访问运算符必须出现在运算对象的左边,运算对象可以是地址(比如&a)或指针变量。(2)取地址运算符“&”和间接访问运算符“*”优先级相同(与++相同),单目、右结合,那么*(&a)可写为*&a。例如:b=*p++;右结合、自右向左运算、相当于b=*(p++);*是加在表达式(p++)上的,是对表达式值间接访问。3、间接访问运算符与指针变量定义中的“*”是不相同的:当定义一个指针变量时,“*”是一个说明符,说明一个变量是一个指针变量,而“*”作为间接访问运算符时意味着取指针变量所指向变量的内容。例:main(){Inta=7,b=8,*p,*q,*r;p=&a;q=&b;r=p;p=q;q=r;printf(“%d,%d,%d.%d”,*p,*q,a,b);}(三)指针移动移动指针就是通过赋值运算,使指针变量加上或减去一个整数,使指针变量指向相邻的存储单元。指针每移动一次则移动一个存储单元。例:p为int类型的指针,且p指向的内存地址为1200,则p=p+1;p指向了1204的存储单元。(画图说明)所以此处1代表是一个存储单元,而不是1个字节,具体这个存储单元是多大,要看指针变量的“基类型”。(四)指针比较设p、q指向同一数据集合的指针变量,如果pq为真表明p指针变量所指的元素在q指针变量所指向的元素之后。同理还有=、=、==、!=都是用来判别同一数据集合中元素的位置关系的。能够用来比较的指针,都可以使用减操作,例如:p-q,结果是存储单元的个数。(画图说明)三、函数之间地址值的传递1、传值与传址调用:函数调用过程中的参数传递分两类:(1)传值:普通变量作为实参的调用为传值调用,形参改变时实参不变,值单向传递。(2)传址:当函数的形参为指针变量时;则调用该函数时,对应的实参也必须是与形参“基类型”相同的地址值或指针变量。形参变化,实参变化。例1:intf(int*a,int*b){ints;s=*a+*b;returns;}voidmain(){intx=2,y=4,s;s=f(&x,&y);printf(%d,s);}例2:传值调用:voidswap(intx,inty){intt;t=x;x=y;y=t;printf(%d%d,x,y);}voidmain(){inta=3,b=4;swap(a,b);printf(%d%d,a,b);}传址调用:voidswap(int*a,int*b){intt;t=*a;*a=*b;*b=t;}voidmain(){inta=3,b=4;printf((1)a=%db=%d\n,a,b);swap(&a,&b);printf((2)a=%db=%d\n,a,b);}例3:#includestdio.hvoidfun(int*a,int*b){int*c;c=a;a=b;b=c;}main(){intx=3,y=5,*p=&x,*q=&y;fun(p,q);printf(%d,%d,*p,*q);fun(&x,&y);printf(%d,%d\n,*p,*q);}程序的结果是:3,5,3,52、函数返回地址:函数返回值类型不仅可以是简单数据类型,还可以是代表地址的指针类型。例:int*fun(int*,int*);main(){inta,b,*p;scanf(%d%d,&a,&b);p=fun(&a,&b);printf(a=%d,b=%d,*p=%d\n,a,b,*p);}int*fun(int*x,int*y){if(*x*y)returnx;returny;}第七章数组一、数组概念:1、数组是一组具有相同类型的数据的集合,这些数据称为数组元素。例如:{1,2,3}整型数组,1,2,3称为数组元素;2、数组在内存中占据连续的内存空间;3、同一数组中元素类型相同,元素的名字包含相同的数组名和不同的下标;4、根据元素下标的个数可以把数组分为:一维数组、二维数组和多维数组。二、一维与二维数组(一)一维数组1、定义:类型名数组名[常量表达式];例如:inta[5];定义了一个一维数组,数组名为a,包含5个int类型元素。(1)数组名是用户定义标识符;(2)方括号不可少,内表达式必须为常量表达式,不能为变量,而且常量表达式的值为正整数,表示数组元素的个数,也称为数组的长度。上例中方括号的5规定了a数组有5个元素,分别是a[0]、a[1]、a[2]、a[3]、a[4]。(3)每个元素的下标只有一个,范围:0~常量表达式值-1。(4)定义之后,a数组在内存中占用5个连续的存储单元,每一个存储单元存放一个整型数据,占用4Bytes内存空间。(画图说明)例:要求定义具有10个int型元素的一维数组a,则下列定义语句中错误的是A)#defineN10inta[N];B)#definen5inta[2*n];C)inta[5+5];D)intn=10;inta[n];2、初始化:定义数组的同时,对数组元素赋初值。有以下几种形式:(1)inta[5]={1,2,3,4,5};(2)inta[5]={1,2};(3)inta[]={1,2,3,4,5};(4)inta[5];a[0]=1;a[1]=2;a[2]=3;a[3]=4;a[4]=5;注意:①当指定数组长度时,不允许赋初值的个数多余数组中元素的个数,例如:inta[3]={1,2,3,4};是不正确的;②赋初值的类型必须与数组类型一致;③在单纯的数组定义中,不能省略数组长度,例如:inta[];是不正确的。3、数组元素的引用:数组名[下标表达式],下标表达式可以是由常量和变量构成的值为正整数的表达式。例如:inta[5]={1,2,3,4,5};则a[0]值为1,a[1]值为2…注意以下几点:(1)数组中的元素就是一个变量,所有适合该类型变量的操作同样适用于数组。例如:a[0]=5;a[0]++;a[1]=a[0]+14;printf(“%d”,a[4]);(2)数组元素的下标,必须是从0开始,到数组的最大长度减1;例:inta[5];a[5]是错的。(3)数组名代表数组的首地址,是一个地址常量,不能整体引用数组里面的所有元素。例1:main(){inti,n[]={0,0,0,0};for(
本文标题:指针数组知识总结计算机二级C辅导
链接地址:https://www.777doc.com/doc-2450877 .html