




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第八章 指針v指針v指針和數組v指針和字符串v指針數組和二級指針v指針和函數8.1 指針變量地址內容int x;x = 3; printf(“%d”, x;)x20013px30002001直接訪問:通過變量名直接訪問地址間接訪問:把變量的地址放到另一變量中,使用時先找到后者的地址,從中取出前者的地址指針變量地址另一變量的地址變量地址內容x20013px30002001指針變量地址另一變量的地址指針變量:存放地址的變量某個變量的地址指向指向int x;x = 3; printf(“%d”, x;)8.1.1 指針變量的定義指針變量所指向變量的類型int *px; px 是整型指針,指向整型變量
2、float *pf; pf 是浮點型指針,指向浮點型變量char *pc; pc 是字符型指針,指向字符型變量類型名 *指針變量名;類型名 * 指針變量名;int *p1, *p2; 等價于 int * p1; int * p2; int *px;注意:指針變量名是 px,不是*px 8.1.2 指針的基本操作*p: p所指向的變量 aa3&ap*p1、&和* & 取地址運算符 * 指針運算符(間接訪問運算符) int *p, a = 3; p&a; 把 a 的地址賦給 p,即 p 指向 aa3&ap*p輸入 5 7輸出:3, 35, 57, 710,
3、10main( ) int a = 3, *p; p = &a; printf(“%d,%dn”, a, *p); scanf(“%d”, &a); printf(“%d,%dn”, a, *p); scanf(“%d”, p); printf(“%d,%dn”, a, *p); *p = 10; printf(“%d,%dn”, a, *p);例8.1指針運算b10&bp2*p2輸出:100, 10100, 10a100&ap1*p1main( ) int a, b; int *p1, *p2; a = 100; b = 10; p1 = &a; p2
4、 = &b; printf(“%d, %dn”, a, b); printf(“%d, %dn”, *p1, *p2);例8.2指針運算a3&ap*p指針運算注意事項(1) 當 p&a 后,*p 與 a 相同。(2) int *p; 定義 *p =10; p所指向的變量(3) &*p 與 &a 相同,是地址 *&a 與 a 相同,是變量a3&ap*p當 p&a 時(4) (*p)+ 等價于 a+ 將p所指向的變量值加1 *p+ 等價于 *(p+) 先取 *p,然后 p 自加,此時p不再指向a2、賦值=a3&ap1p2p1;
5、 p2 也指向 a&ap2*p1 *p2int *p1, *p2, a=3;p1&a; 把 a 的地址賦給 p1,即 p1 指向 a輸出:10, 100例8.3指針賦值main( ) int a, b; int *p1, *p2; a = 100; b = 10; p1 = &a; p2 = p1; p1 = &b; printf(“%d, %dn”, *p1, *p2);b10p1a100p28.1.3 指針變量的初始化例8.4-1 void main( ) int a=1, b=2; int *p1= &a, *p2=&b, *pt; pri
6、ntf(“%d, %dn”, *p1, *p2); pt = p1; p1 = p2; p2 = pt; printf(“%d, %dn”, *p1, *p2);b2&bp2a1&ap1b2&ap2a1&bp18.1.3 指針變量的初始化例8.4-2void main( ) int a=1, b=2; int *p1= &a, *p2=&b, t; printf(“%d, %dn”, *p1, *p2); t = *p1; *p1 = *p2; *p2 = t; printf(“%d, %dn”, *p1, *p2);b2&bp2a1&a
7、mp;ap1b1&bp2a2&ap18.1.4 指針作為函數的參數swap1(int x, int y) int t; t = x; x = y; y = t;輸出:3, 5a35bx35yx53y例 8.5main( ) int a=3, b=5; swap1(a, b); printf(“%d, %dn”, a, b);swap2(int *p1, int *p2) int t; t = *p1; *p1 = *p2; *p2 = t;輸出:5, 335abp1p25335值傳遞,地址未變,但存放的變量的值改變了main( ) int a=3, b=5; swap2(&am
8、p;a, &b); printf(“%d, %dn”, a, b);int max(int *x, int n) int m=*x; int i; for(i=1;im) m=xi; return m;int max(int *x, int n) int m=*x; int i; for(i=1;im) m=*(x+i); return m;#define N 10Main() int max(int *,int); int aN=1,0,34,56,78,90,-3,675,3,12; printf(“%d”,max(a,N);swap3(int *p1, int *p2) int
9、*p; p = p1; p1 = p2; p2 = p;35abp1p2值傳遞,形參指針的改變不會影響實參main( ) int a=3, b=5; swap2(&a, &b); printf(“%d, %dn”, a, b);輸出:3, 5swap2(int *p1, int *p2) int t; t = *p1; *p1 = *p2; *p2 = t;main( ) int a=3, b=5; swap2(&a, &b); 要使某個變量的值通過函數調用發生改變(1) 在主調函數中,把該變量的地址作為實參(2) 在被調函數中,用形參(指針)接受地址(3) 在
10、被調函數中,改變形參(指針)所指向變量的值例8.6-1 指針作為函數的參數void p(int *a, int b) *a = *a -1; b+;void main( ) int x = 3, y = 5; p(&x, y); printf(%d,%dn,x,y);調用前 main :x = 3, y = 5調用p:*a b 3 5 2 6調用后 main :x = 2, y = 5將變量的地址作為實參,調用后,該變量的值可能改變例8.6-2void p(int *a, int b) *a = *a -1; b+;void main( ) int x = 3, y = 4; p(&a
11、mp;y, x); printf(%d,%dn,x,y); 調用前 main :x = 3, y = 4調用p:*a b 4 3 3 4調用后 main :x = 3, y = 3例8.6-3void p(int *a, int b) *a = *a -1; b+;void main( ) int x = 3, y = 5; p(&x, y); printf(%d,%dn,x,y); p(&y, x); printf(%d,%dn,x,y); 調用前 main :x = 3, y = 5第1次調用p: *a b 3 5 2 6調用后 main :x = 2, y = 5第2次調
12、用p: *a b 5 2 4 3調用后 main :x = 2, y = 4例7-9自定義函數dayofyear(year,month,day), 返回該年的第幾天。dayofyear(2000,3,1)返回61dayofyear(1981,3,1)返回60分析: 月 0 1 2 311 12非閏年 0 31 28 31 30 31閏年 0 31 29 31 30 31int tab213=0, 31, 28, 31, 30,31,30,31,31,30,31, 30,31 0, 31, 29, 31, 30,31,30,31,31,30,31, 30,31例8-9Void dayofyear
13、(int year, int month, int * day) int k, leap; int tab213=0, 31, 28, 31, 30,31,30,31,31,30,31, 30,31 0, 31, 29, 31, 30,31,30,31,31,30,31, 30,31; leap=(year%4=0&year%100!=0) | year %400=0; for (k=1; kmonth; k+) *day=*day+tableapk; /* return day;*/Main() int day=29; days(2007,5,&day); day;Int d
14、ayofyear(int year, int month, int day) int k, leap; int tab213=0, 31, 28, 31, 30,31,30,31,31,30,31, 30,31 0, 31, 29, 31, 30,31,30,31,31,30,31, 30,31; leap=(year%4=0&year%100!=0) | year %400=0; for (k=1; ktableapk; k+) yearday = yearday - tableapk; *pmonth=k; *pday=yearday; 8.2 指針和數組8.2.1 指針、數組、地
15、址間的關系8.2.2 數組名做為函數的參數8.2.1 指針、數組、地址間的關系指針和數組有密切的關系任何由數組下標來實現的操作都能用指針來完成。int a10;a0a1a9ai數組名是一個指針它的值是數組首元素的地址即它指向數組的首元素aint *ap;ap = &a0;ap 指向數組a的首元素a0a1a9aiaa+1a+ia+9*(a+i)&ai或: ap = a;ap,ap+i,*(ap+i)ai的地址 &ai a+i 、ap+iai 相當于 *(a+i) *(ap+i)、api2000a0a1a9aiaa+1a+ia+9*(a+i)&aiap,for(i=
16、0; i10; i+) printf(”%d”, *(a+i)for(ap=a; apa+10; ap+) printf(”%d”, *ap)注意: 數組名 a 是指針常量 ,不能 a+for(i=0; i10; i+) printf(”%d”, ai)例:輸出數組a所有元素1、數組元素作為函數實參 函數形參為變量 (與變量作為函數實參相同,值傳遞)2、數組名作為函數參數由于數組名是指針常量,相當于指針作為函數的參數數組名做為實參 形參是指針變量(數組)8.2.2 數組名作為函數的參數float average( float *array) int i; float aver,sum=0; f
17、or(i=0; i10; i+) sum+=arrayi; *(array+i) aver=sum/10; return(aver); main( ) float score10, aver; int i; for(i = 0; i 10; i+) scanf(“%f”, &scorei); aver = average(score); printf(%fn, aver);(1) 實參是數組名(2) 形參是指針變量 可以寫成數組形式 可以不指定長度float array10例 8.8 求平均分float array float average( float *array) int i;
18、 float aver,sum=0; for(i=0; i10; i+) sum+=arrayi; aver=sum/10; return(aver); main( ) float score10, aver; int i; for(i = 0; i 10; i+) scanf(“%f”, &scorei) aver = average(score); printf(%fn, aver);score score0score9array*(array+i)(3) 若在函數中只處理部分數組元素,用參數指定個數float average(float *array, int n) int i;
19、 float aver, sum=0; for(i=0; in; i+) sum += arrayi; aver=sum/n; return(aver);main() float score20, aver; int i; for(i = 0; i aj+1j=0 to 4j=0 to 3j=0 to 2j=0 to 6-1-i9 8 8 8 8 8 5 4 4 0 8 9 5 5 5 5 4 5 0 45 5 9 4 4 4 6 0 54 4 4 9 6 6 0 66 6 6 6 9 0 80 0 0 0 0 9 9 8 5 4 6 0i=1j=0: 8 9 5 4 6 0j=1: 8 5
20、9 4 6 0j=2: 8 5 4 9 6 0j=3: 8 5 4 6 9 0j=4: 8 5 4 6 0 9main( ) int i, j, n, t, a10; n=6; for(i=0; in; i+) scanf(%d, &ai); for(i=1; in; i+) for(j=0; j aj+1) t = aj; aj = aj+1; aj+1 = t; main() int i, a10; ; for(i=0; i10; i+) scanf(%d, &ai); sort(a, 10); for(i=0; i10; i+) printf(%d , ai); prin
21、tf(n);void sort(int *array, int n) int i, j, t; for(i=1; in; i+) for(j=0; jarrayj+1) t = arrayj; arrayj = arrayj+1; arrayj+1 = t; 8.3 指針和字符串8.3.1 常用的字符串處理函數8.3.2 字符串的指針表示8.3.3 字符數組和字符指針8.3.1 常用的字符串處理函數1、使用printf函數和scanf函數輸入輸出字符串用%s格式,將字符串一次性輸入輸出static char str20=“Hello”; 輸出printf(%s, Hello);printf(%
22、s, str); 注意:遇到 0,輸出結束for(i=0;stri!=0 ;i+) putchar(stri);字符數組名輸出:HelloHello 輸入 scanf(%s, str); 注意: 輸入參數使用數組名,不加地址符。 遇到回車或空格,輸入結束,并自動在末尾加0。H o w 0輸入 How are you? str中:while(stri=getchar( )!= ) i+;si=0; 輸入多個用空格分隔的字符串 char s120, s220, s320; scanf(%s%s%s, s1, s2, s3);s1:H o w 0a r e 0Y o u ? 0s2:s3:字符串可以
23、一次性輸入輸出一般的字符數組只能逐個字符輸入輸出輸入 How are you? 2、字符串輸出函數puts static char str20=“hello”; puts(str); 輸出:Helloputs(“World!”);輸出:World! 輸出:Hello World! puts(str)與 printf(“%s”, str)的區別: puts(str); = printf(%sn, str);自動將結束符 0 轉換成 nputs(“Hello”); puts(“World!”); 輸出:HelloWorld! printf(“%s”,“Hello”); printf(“%s”,“W
24、orld!”); static char str20; gets(str); 字符數組名3、字符串輸入函數gets輸入遇空格不結束,只有遇回車才結束。 gets(str); 輸入:hello! str中: hello!0gets(str) 與 scanf(“%s”, str) 的區別:遇到回車或空格,輸入結束例:gets(str); 輸入:How are you? Str: How are you?0 scanf(“%s”, str); 輸入:How are you? Str: How0遇回車,輸入結束strcpy(str1, str2);將字符串 str2 復制到 str1 中 static
25、 char str120; static char str220 = “happy”;4、字符串復制函數strcpyh a p p y 00strcpy(str1, str2);h a p p y 0str1中strcpy(str1, “ world”);str1中: world0# include “stdio.h”# include “string.h”main( ) char str120, str220; gets(str2); strcpy(str1,str2); puts(str1);輸入:1234輸出:1234 strcat(str1, str2); 連接兩個字符串str1和st
26、r2, 并將結果放入str1中。5、字符串連接函數strcat # include “stdio.h”# include “string.h”main( ) char str180, str220; gets(str1); gets(str2); strcat(str1, str2); puts(str1);輸入:Let us go. 輸出:Let us go.str1中: Let us 0 str2中:go.0str1中: Let us go.0strcmp(str1, str2)比較 兩個字符串str1和str2的大小。規則:按字典序(ASCII碼序)如果 str1 和 str2 相等,函
27、數值是 0; 如果 str1 大于 str2 ,函數值是正整數; 如果 str1 小于 str2 ,函數值是負整數; 6. 字符串比較函數strcmp如果 str1 和 str2 相等,函數值是 0; 如果 str1 大于 str2 ,函數值是正整數; 如果 str1 小于 str2 ,函數值是負整數;static char s120 = “china”;strcmp(“China”, “China ”)strcmp(s1, “china”)正整數負整數0strcmp(s1, “China ”)# include “stdio.h”# include “string.h”main( ) int
28、 res; char s120, s220; gets(s1); gets(s2); res = strcmp(s1, s2); printf(“%d”, res);輸入:1234 5 輸出:-4利用字符串比較函數比較字符串的大小 strcmp(str1, str2); 為什么定義這樣的函數? 因為 str1 str2 str1 0strcmp(str1, “hello”) s1strcat(s1,s2) s1 + s2=s1strcmp(s1,s2) 若 s1 = s2, 函數值為0 若 s1 s2, 函數值 0 string.h 若 s1 s2, 函數值0strlen(str) 計算字符串
29、的有效長度, 不包括0字符串處理函數小結8.3.2 字符串的指針表示1、用字符數組表示字符串static char sa =“This is a string.”;printf(“%s”, sa);printf(“%s”, “Hello”);sa0sa1saisa2、用字符指針表示字符串字符串是一個指針常量它的值就是該字符串的首地址由于字符串是一個指針常量定義一個字符指針,接收字符串指針常量char *sp= This is a string.;printf(%s, sp);8.3.2 字符串的指針表示static char sa =“This is a string.”;printf(“%s
30、”, sa);printf(“%s”, “Hello”);1、使用字符指針進行字符串操作實現字符串復制函數 strcpy(s1,s2)8.3.3 字符數組和字符指針void strcpy(char s1 , char s2 ) int i; for( i=0; s2i!=0; i+) s1i = s2i; s1i = 0;void strcpy(char s1 , char s2 ) int i = 0; while (s1i = s2i) i+;用字符指針實現字符串復制函數 strcpy(s1,s2)void strcpy(char s1 , char s2 ) int i = 0; whi
31、le (s1i = s2i) i+;void strcpy(char *s1, char *s2) while ( *s1= *s2) s1+; s2+; void strcpy(char *s1, char *s2) while ( *s1+ = *s2+);數組:改變下標指針:直接改變指針實現字符串長度函數strlen(str)int strlen(char str ) int i=0; while(stri != 0) i+; return i;int strlen(char *str) char * t=str; while(*str!= 0) str+; return str-t;實
32、現字符串比較函數strcmp(s1,s2)int strcmp(char s1 , char s2 ) int i; for( i=0; s1i != 0; i+) if(s1i != s2i) break; return s1i-s2i;strcmp(char *s1,char *s2) for(; *s1 != 0; +s1, +s2) if(*s1 != *s2) break; return(*s1 - *s2); static char sa =“This is a string.”;字符數組sa由若干元素組成的,每個元素放一個字符,有確定的地址。char * sp=“This is
33、a string.”;字符指針是一個接收字符串首地址的變量,不能將字符串放到字符指針變量中去。在對指針賦值前,它的值是不確定的。2、字符指針和字符數組的區別static char sa =“This is a string.”;char * sp=“This is a string.”;static char sa80;char * sp;數組,指針常量,有確定的地址指針,變量strcpy(sa, “This is a string.”)sa = “This is a string.”;sp = “This is a string.”;# include stdio.hmain( ) stat
34、ic char sa =“string”; /*設sa的值 2000 */ char *sp ; /*設sp的值 1fff */ printf(n sa=%x, sp=%xn, sa, sp);sp = sa;printf(sa=%x, sp=%xn, sa, sp);printf(%s, , sa);printf(%sn, sp);輸出:2000, 1fff 2000, 2000 string, string例8.10# include stdio.hmain( ) char sa80; /*設sa的值 2000 */ char *sp=“This is a string”; /*設sp的值
35、 1fff */ printf(nsa=%x, sp=%xn, sa, sp); strcpy(sa, sp); printf(sa=%x, sp=%xn, sa, sp); printf(%s, sp); printf(%sn, sp);輸出:2000, 1fff 2000, 1fff string, string指針變量必須先定義,后使用。例如: char *p; scanf(%s, p);可能出現難以預料的結果而 char *s, str20; s = str; scanf(%s, s);是正確的.8.4 指針數組和二級指針8.4.1 指針數組8.4.2 二級指針8.4.3 指針數組和字
36、符串int i;int a10;a是一個數組,它有10個元素,每個元素的類型都是整型。int *p;int *pa10;pa是一個數組,它有10個元素,每個元素的類型都是整型指針。8.4.1 指針數組int a10;a0a9aiaint *pa10; pa0pa9paipaint i, j, k, m;int *pa4;pa0=&i;pa1=&j;pa2=&k;pa3=&m;pa0papa1pa2pa3ijkm*pa0*pa1*pa2*pa3int i=1, j=2, k=3, m=4;int *pa4=&i, &j, &k, &
37、m;pa0papa1pa2pa3ijkm*pa0*pa1*pa2*pa31234for( n=0; n4; n+) printf(“%x”, pan);for( n=0; n4; n+) printf(“%d”, *pan);int i=1, j=2, k=3, m=4;int *pa4=&i, &j, &k, &m;for( pp=pa; pppa+4; pp+) printf(“%x”, *pp);pp,*pp*pppa0papa1pa2pa3ijkm*pa0*pa1*pa2*pa31234for( pp=pa; pppa+4; pp+) printf(“%
38、x”, *pp);int i=1, j=2, k=3, m=4;int *pa4=&i, &j, &k, &m;如何定義 pp*pp*pppp,pa0papa1pa2pa3ijkm*pa0*pa1*pa2*pa31234int *pp;8.4.2 二級指針(指向指針的指針)main() int a = 10;int *p = &a, *pp = &p; printf(a=%d,*p=%d,*pp=%dn,a,*p,*pp);*p = 20;printf(a=%d,*p=%d,*pp=%dn,a,*p,*pp);*pp = 30; printf(a
39、=%d,*p=%d,*pp=%dn,a,*p,*pp);&apa10&ppp*p*pp&a*pp輸出:a=10,*p=10,*pp=10 a=20,*p=20,*pp=20 a=30,*p=30,*pp=30main() int a = 10, b = 80;int *p = &a, *pp = &p; printf(a=%d,b=%d,*p=%d,*pp=%dn,a,b,*p,*pp);p = &b; printf(a=%d,b=%d,*p=%d,*pp=%dn,a,b,*p,*pp);&apa10&ppp*p*pp&a
40、*pp輸出:a=10,b=80,*p=10,*pp=10 a=10,b=80,*p=80,*pp=80&bpa10&ppp*pp&bb80*pp*pchar *name4=“Wang”, “Li”, “Zhao”, “Jin”;8.4.3 指針數組和字符串name0name“Wang”name1“Li”name2“Zhao”name3“Jin”printf(“%sn”, name0);printf(“%c”, *name0);輸出:WangW char *name4=“Wang”, “Li”, “Zhao”, “Jin”;name0name“Wang”name1“Li”
41、name2“Zhao”name3“Jin”輸出:Wang Li Zhao Jin for( i=0; i4; i+) printf(“%s ”, namei);for( i=0; i4; i+) printf(“%c ”, *namei);輸出:W L Z J 輸入月,輸出相應的英文名稱。#include main( ) int month; scanf(%d,&month); if (month=1 & month=12) prnname(month);例8.11prnname(int m) char *name =January, February, March, April,May,June,July, August, September, October, November,December; pr
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 不定積分在解決實際問題中的應用教案
- 跨境電商與全球消費市場的發展前景
- 介詞與冠詞的使用區別及其在實際句子中的運用教案
- 小學生學科自信心的提升路徑
- 音樂表演藝術考試試題及答案
- 低空經濟中的科技創新與技術突破
- DB13T 1320.9-2010 中藥材種子質量標準 第9部分:白芷
- 高端酒店式公寓租賃與管理協議
- 農業文化遺產景觀的視覺美學對游客停留時間的影響
- 服裝品牌銷售排名表
- 揭陽惠來縣紀委監委等部門屬下事業單位招聘筆試真題2024
- 黨課課件含講稿:以作風建設新成效激發干事創業新作為
- 超市百貨考試試題及答案
- 2025年北京市東城區九年級初三二模物理試卷(含答案)
- 現代控制理論知到智慧樹期末考試答案題庫2025年長安大學
- 2025年北京市平谷區九年級初三二模英語試卷(含答案)
- 脊柱感染的護理
- 【正版授權】 IEC 60512-99-002:2022/AMD1:2025 EN-FR Amendment 1 - Connectors for electrical and electronic equipment - Tests and measurements - Part 99-002: Endurance test schedules - Tes
- 蘇州市昆山市惠民物業管理有限公司招聘考試真題2024
- 2025年南昌職教城教育投資發展有限公司招聘筆試參考題庫附帶答案詳解
- 綜合呈現2025年入團考試試題及答案
評論
0/150
提交評論