版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、指针C语言内容提要指针的概念;难点:对指针数据类型的理解 数组的下标法引用和指针法引用;难点:二维数组的地址和指针概念 利用字符指针存取字符串;难点:字符数组和字符指针的区别与联系 指针数组应用;难点:指向数组的指针与指针数组的区别 带参数的main函数;10.1地址和指针的概念printf (“%d,i);scanf (“%d, &i);k = i+j;内存区的每一个字节有一个编号,这就是“地址 。程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元,但是没有赋值。“直接访问方式:按变量地址存取变量的值“间接访问的方式:将变量的地址存放在另一个变量中例如“间接访问的方式:
2、将变量的地址存放在另一个变量中。在语言中,指针是一种特殊的变量,它是存放地址的。可以通过语句: int i; i_pointer =;指针和指针变量的定义:一个变量的地址称为该变量的“指针。指针变量的值(即指针变量中存放的值)是地址(即指针)。请区分“指针和“指针变量这两个概念。10.2 变量的指针和指向变量的指针变量2000i_pointer3* i_pointer200010.2.1 定义一个指针变量指针变量的定义包括三个内容:指针类型说明,定义变量为一个指针变量;指针变量名;变量值(指针)所指向的变量的数据类型, 基类型。其一般形式为:类型说明符 *变量名;其中,*表示这是一个指针变量,
3、变量名即为定义的指针变量名,类型说明符表示本指针变量所指向的变量的数据类型。下面都是合法的定义:float *pointer_1;/ pointer_1是指向float型变量的指针变量char *pointer_2;/pointer_2是指向字符型变量的指针变量可以用赋值语句使一个指针变量得到另一个变量的地址,从而使它指向一个该变量。如:float i;char j;pointer_1=&i;pointer_2=&j;*pointer_1=i;类型说明要一致注意指针变量前面的“*,表示该变量的类型为指针型变量。例: float *pointer_1;指针变量名是pointer_1 ,而不是*
4、pointer_1 。 在定义指针变量时必须指定基类型。float a;int * pointer_1; pointer_1=&a; 10.2.2 指针变量的引用指针变量中只能存放地址(指针),不要任何其他非地址类型的数据赋给一个指针变量。例10. 通过指针变量访问整型变量#include voidmain ( ) int a,b; int*pointer_1, *pointer_; a=100;=10; pointer_1=&a; pointer_2=&b; printf ( “%d,%dn, a,b ); printf( “%d,%dn, *pointer_,*pointer_); 100
5、10&a100ap1&b10bp2p2=p1&a100ap1&b100bp2*p2=*p1对“和“*运算符说明:a=3;&a=23f1;pointer_=;* pointer_的含义是什么?*&a含义是什么?y=(* pointer_1) +y=+* pointer_1y=* pointer_1+y=* (pointer_1+)y=* +pointer_1 * pointer_的含义是什么?“和“*两个运算符的优先级别相同,右结合& * pointer_= & a*的含义是什么?先进行运算,得的地址,再进行*运算。即所指向的变量,也就是变量a。*和*pointer_的作用是一样的,它们都等价于
6、变量。即*与等价。 (*pointer_1)+和*pointer_1+的区别?(*pointer_)+相当于+。*pointer_ + ,从附录可知:+和*为同一优先级别,而结合方向为自右而左,因此它相当于*(pointer_ +)。由于+在pointer_1的右侧,是“后加,因此先对pointer_的原值进行*运算,得到的值,然后使pointer_的值改变,这样pointer_不再指向了。例10.2输入和两个整数,按降序序输出a,b#include void main() int *p1,*p2,*p, a, b; scanf(%d,%d,&a, &b); p1=&a; p2=&b; if
7、(ab) p=p1 ; p1=p2; p2=p; printf (na=%d, b=%dn, a, b); printf (max=%d, min=%dn, *p1, *p2);交换的是变量的地址a,b的值没有变,但p1,p2的值交换了&aap1&bbp2&aap1&bbp2运行情况如下:5,9= 5,= 9 max = 9, min = 5#include void main() int *p1,*p2, p, a, b; scanf(%d,%d,&a, &b); p1=&a; p2=&b; if (ab) p=*p1 ; *p1=*p2; *p2=p; printf (na=%d, b=%
8、dn, a, b); printf (“max=%d, min=%dn, *p1, *p2);printf (“na=%d, b=%dn, a, b); printf (max=%d, min=%dn, p1, p2);交换的是变量的值955910.2.3 指针变量作为函数参数例10.3 对输入的两个整数按大小顺序输出 #include swap(int *p1, int *p2 ) int temp; temp=*p1; *p1=*p2; 偶 *p2=temp; printf(n%d,%dn, *p1, *p2);void main() int a,b; int *pointer_1,*po
9、inter_2; scanf(%d,%d,&a,&b); printf(n%d,%dn,a,b); pointer_1=&a; pointer_2=&b; if (ab) swap(pointer_1, pointer_2); printf(n%d,%dn,a,b); printf(n%d,%dn, *pointer_1, *pointer_2); 交换的是地址中的值所以a,b中的值改变了指针变量按值传递方式,指针地址没变955910.2.3 指针变量作为函数参数例10.3 对输入的两个整数按大小顺序输出 #include swap(int *p1,int *p2) int temp; tem
10、p=*p1; *p1=*p2; *p2=temp; printf(n%d,%dn, *p1, *p2);void main() int a,b; scanf(%d,%d,&a,&b); printf(n%d,%dn,a,b); if (ab) swap( &a, &b ); printf(n%d,%dn,a,b); 交换的是地址中的值所以a,b中的值改变了变量地址按值传递,地址没变,但调用函数后,地址中的值变化了注意:三种错误表示方法void swap (int *p1, int *p2) int *temp; *temp=*p1; *p1=*p2; *p2=*temp;void swap (
11、int x, int y) int temp; temp=x; x=y; y=temp; 错误:原意是将temp指向的值和 p1 指向的值交换,但是, temp只是定义了,没有地址的值,所以*temp就不知是何物。在函数内部x和y的值交换了,但是在主程序中没交换void swap (int *p1, int *p2) int *temp,i; temp=&i; *temp=*p1; *p1=*p2; *p2=*temp;void main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointe
12、r_2=&b; if (apf2表示pf1处于高地址位置; pf1b) pmax=&a; pmin=&b; else pmax=&b; pmin=&a; if (c*pmax) pmax=&c; if (c*pmin) pmin=&c; printf(max=%dnmin=%dn,*pmax,*pmin); 10.3 数组与指针数组名是地址。一个数组包含假设干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元素的地址。10.3.1 指向数组元素的指针定义一个指向数组元
13、素的指针变量 int a10, *p; p=&a0; 或p=a;在定义指针变量时可以赋给初值:int *p=&a0; 它等效于:int *p; p=&a0;定义时也可以写成: int *p=a通过指针引用数组元素假设有一个a数组,整型,有10个元素引用一个数组元素,可以用:下标法,如ai形式;指针法,如*(a+i) 或 *(p+i) 。a数组名,p是指向数组元素的指针变量,其初值p=a。注意:int a12,*p; p=a; *(a+1) *(p+1) p+; a+;a=a+1, 这样a的值就改变了,但是a是数组的首地址,是常量,所以这个表达式是错的。例10.5 输出数组中的全部元素下标法#i
14、nclude void main() int a10, i; for ( i=0; i10; i+)scanf (“%d,&ai); printf (“n); for ( i=0; i10; i+)printf (“%d,ai );通过数组名计算数组元素地址,找出元素的值。#include void main() int a10, i; for ( i=0; i10; i+)scanf ( “%d, &ai ); printf (“n); for ( i=0; i10; i+)printf ( “%d, *(a+i) );用指针变量指向数组元素#include void main() int
15、a10, *p, i; for ( i=0; i10; i+)scanf ( “%d, &ai ); printf (“n); for (p=a; p(a+10); p+) printf (“%d, *p);例10.6 指针变量输出a数组的10个元素。 #include void main() int *p,i,a10; p=a; for (i=0; i10; i+) scanf (“%d,p+); printf (“n); for (i=0; i10; i+,p+) printf (“%d,*p); 运行情况:1 2 3 4 5 6 7 8 9 0 22153 234 0 0 30036 2
16、5202 11631 8259 8237 28483 显然输出的数值并不是数组中各元素的值解决这个问题的方法,只要在第二个for循环之前加一个赋值语句:p=a;#include void main() int *p,i,a10; p=a; for (i=0; i10; i+) scanf (“%d,p+); printf (“n); p=a; for (i=0; i10; i+, p+) printf (“%d,*p); 为什么要重新赋值10.3.3 用数组名作函数参数数组名作函数的参数如: void main() f (int arr,int n); int array10; f( arra
17、y ,10) ; void f (int arr,int n) f (int arr, int n)f (int *p, int n)以上两种写法是等价的。 例10.7 将数组a中n个整数按相反顺序存放#include #define N 100void main() void inv ( int x,int n); int i,aN =3,7,9,11,6,7,5,4,2; printf (“The original array:n); for(i=0;i10;i+) printf (“%d, ai ); printf (“n); inv (a,10); printf (“The array
18、 has been inverted:n); for(i=0;i10;i+) printf (“%d, ai ); printf (“n);数组名实参代替形参void inv(int x, int n) int temp,i,j,m=(n-1)/2; for (i=0; i=m; i+) j=n-1-i; temp=xi; xi=xj; xi=temp; 运行情况如下:The original array:,The array has been inverted:,整个函数中数组的值被置逆,数组的值发生了改变。#include void main() void inv(int *,int n)
19、; int i, a =3,7,9,11,0,6,7,5,4,2; printf (“ The original array: n ) ; for (i=0; i10; i+)printf (“ %d ,ai ); printf (“n ) ; inv ( a, 10 ) ; printf (“The array has been in verted: n ) ; for (i=0; i10; i+) printf (“ %d , ai ); printf (“n ) ;对置逆程序作一些改动。将函数inv中的形参改成指针变量。 void inv ( int *x, int n) int p,
20、m,temp, *i,*j; m=(n-1)/2; i=x; j=x+n-1; p=x+m; for (; i=p; i+; j- - ) temp=*i; *i=*j; *j=temp; 归纳起来,如果有一个实参数组,想在函数中改变此数组中的元素的值,实参与形参的对应关系有以下种情况: void main() int a10; f(a,10);形参和实参都用数组名void f( int x, int n) void main() void f (int *,int n) int a10; f(a,10); void main() void f (int *x,int n) int a10 ,
21、*p=a; f(p,10); 实参用数组名,形参用指针变量实参形参都用指针变量void main() void f ( int x,int n) int a10, *p=a; f(p,10); 实参用指针变量,形参为数组名#include void main() void inv(int *,int n); int i, arr10, *p=arr; printf (“ The original array: n ) ; for ( i=0; i10; i+, p+) scanf (“ %d , p ); printf (“n ) ; p=arr; inv ( p, 10 ) ; printf
22、 (“The array has been in verted: n ) ; for (p=arr; parr+10; p+) printf (“ %d , *p ); printf (“n ) ;void inv (int *x, int n) int p, m,temp,*i,*j; m=(n-1)/2; i=x; j=x+n-1; p=x+m; for (; i=p; i+; j- - ) temp=*i; *i=*j; *j=temp; 几个注意的问题:指针变量可以实现本身的值的改变。p+是合法的;a+是错误的。因为a是数组名,它是数组的首地址,是常量。*p+,由于+和*同优先级,右结
23、合,等价于*(p+)。*(p+)与*(+p)作用不同。假设p的初值为a,那么*(p+)等价求得a0,p指向a1 ;*(+p)等价求得a1, p指向a1 。 (*p)+表示p所指向的元素值加1。如果p当前指向a数组中的第i个元素,那么 *(p-)相当于ai-; *(+p)相当于a+i; *(-p)相当于a-i。float aver(float *pa);void main() float sco5, av, *sp ; int i; sp=sco; printf(ninput 5 scores:n); for(i=0;i5;i+) scanf(%f,&scoi); ver(sp,&av); pr
24、intf (average score is %5.2f, av);void aver( float *pa, int *av) int i,s=0; for(i=0;i5;i+) s=s+ *pa+ ; *av=s/5;例10.9 用选择法对10个整数按由大到小顺序排序 #includevoid main() int *p,i,a100,n; printf (The original array:n); n=inputarr(a); printf(n); p=a; sort(p,10); for(p=a,i=0;i10;i+) printf(%d ,*p); p+; printf(n);vo
25、id sort(int x,int n) int i,j,k,t; for (i=0;in-1;i+) k=i; for (j=i+1;jxk) k=j; if (k!=i) t=xi; xi=xk; xk=t; 10. 字符串与指针字符串的表示形式 (1) 用字符数组存放一个字符串,然后输出该字符串。用字符串指针指向一个字符串void main() char *string=I love China!; printf(%sn,string);输出字符串中n个字符后的所有字符void main() char *ps=this is a book; int n=10; ps=ps+n; prin
26、tf(%sn,ps);例 将字符串复制为字符串 对字符串中字符的存取,可以用下标方法,也可以用指针方法 #include void main() char =“ am a boy,b20; int i; for ( i=0; *(a+i)!=0; i+ )*(b+i) =*(a+i); *(b+i) =0; printf(string a is :%n,a); printf( string b is:); for ( i=0; bi!=0; i+ ) printf(%c,bi ); printf(n); 也可以设指针变量,用它的值的改变来指向字符串中的不同的字符。 例用指针变量来处理将字符串复
27、制为字符串#include void main() char a =“I am a boy. ,b20,*p1,*p2; int i; p1=a;p2=b; for(;*p1!=0;p1+,p2+) * p2 =*p1;* p2 =0; printf (string a is:n, a ); printf (string b is :) ; for ( i=0; bi!=0; i+) printf (“%c,bi ); printf (“ n);程序必须保证使p1和p2同步移动。 10.4.2 字符指针作函数参数例10.19 用函数调用实现字符串的复制 #include void main()
28、 void copy_string(char from, char to); char a =“ am a teacher.; char b =“you are a student.; printf(“string a=%n string b=%sn a,b); printf(copy string a to string b:n ); copy_string (a,b); printf(“nstring a=%snstring b=%sn“, a,b); (1) 用字符数组作参数void copy_string(char from. char to)( int i=0; while (fro
29、mi!=0) toi = fromi; i+ ; toi =0;程序运行结果如下:string a = I am teacher.string b=you are a student.copy string a to string b:string a = I am teacher. string b= I am teacher. () 形参用字符指针变量 #include void main() void copy_string(char *from, char *to); char *a = “ am a teacher .; char *b = “you are a student .;
30、 printf (string a=%snsrring b=%sn, a,b); printf (copy string a to string b:n ); copy_string(a,b); printf(“nstring a=%snstring b=%sn“, a,b); void copy_string (char *from,char *to) for (;*from!= 0; from+, to+) *to=*from ;*to= 0 ; 将copy_string函数改写为void copy_string (char * from ,char * to ) while ( * to
31、 = * from ) != 0) to +; from +; (3) 对 copy_string 函数还可作简化 2、 copy_string函数的函数体还可改为 while (*to+ = *from+) != 0) ; 3、copy_string函数的函数体还可写成 while ( *from ! = 0 ) *to+ = *from +; *to = 0 ;4、上面的while语句还可以进一步简化为下面的while语句:while (*to+ = *from+) ;它与下面语句等价:while (*to+=*from+) !=0);将*from赋给*to,如果赋值后的*to值等于0,那
32、么循环终止( 0已赋给*to) 5、函数体中while语句也可以改用for语句:for (; ( *to += *from+)!=0;) 或for(;*to += *from+;);6、也可用指针变量,函数copy_string可写为void copy_string ( char from, char to ) char *p1, p2; p1 = from ; p2 = to; while ( *p2+ = *p1+ ) != 0 );10.5 指向函数的指针10. 用函数指针变量调用函数可以用指针变量指向整型变量、字符串、数组,也可以指向一个函数。一个函数在编译时被分配给一个入口地址。这个
33、函数的入口地址就称为函数的指针。 例 求和中的大者。先列出按一般方法的程序。#include voidmain() int max(int,int); int a,b,c; scanf(“%d,%d,a,b); c=max(a,); printf(“a=%,=%,max=%d , a,b,c); int max(int x,int y) int ; if(xy) z=; else z=y; return(z); 例:求和中的大者。先列出按一般方法的程序。将 main 函数改写为#include voidmain() int max(int,int); int (*p)(); int a,b,c; p=max(); scanf(%d,%d,a,b); c = (*p)(a,b); printf(“= %d,b=%d,max=%d, a,b,c); 10.7指针数组和指向指针的指针10.7
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 水产螃蟹购销合同范本
- 租赁协议到期结束合同
- 物业临时物业合同范本
- 汽车客车出租合同范本
- 文印晒服务合同范本
- 水系综合整治合同范本
- 政府外包物业合同范本
- 重庆店面转让合同范本
- 文玩个人买卖合同范本
- 抚州市数字经济投资集团有限公司高素质人才引培招聘笔试历年参考题库附带答案详解
- 玉米秸秆饲料销售合同
- DGTJ08-10-2022 城镇天然气管道工程技术标准
- 《丝绸之路的开通与经营西域》课件
- 2025八年级英语上册期末真题卷
- 重症康复治疗的原则与方法
- 2025及未来5年中国汽车/摩托车专用焊机市场调查、数据监测研究报告
- 有奖问答题目及答案保险
- GB/T 23720.3-2025起重机司机培训第3部分:塔式起重机
- 2025年中国大唐集团有限公司应届毕业生招聘笔试历年参考题库附带答案详解
- 护理人员警示教育
- 2024 电动垂直起降航空器(eVTOL)起降场技术要求
评论
0/150
提交评论