作業(yè)整理濒翻;
指針的基本的結(jié)構(gòu)與基礎(chǔ)知識(shí)整理屁柏;
作業(yè)講解:
(1) 將2~100之間的素?cái)?shù) 保存到數(shù)組中,并遍歷輸出有送,每五行一個(gè)
include<stdio.h> #define N 50 int main() { int arr[N]; int i=2; int j=0; int k=0; for(i=2;i<100;++i) { for(j=2;j<i;j++) { //從2開始遍歷前联,查找能被i整除的數(shù), //若找到則跳出內(nèi)層循環(huán) if(i%j==0) break; } //若i==j娶眷,則i是素?cái)?shù)似嗤,否則不是 if(i==j) { arr[k]=i; k++; printf("%4d",i); if(k%5==0) printf("\n"); } } }
(2) 在一個(gè)升序或降序排列的數(shù)組中,插入一個(gè)元素届宠;提示:數(shù)組元素部分初始化
(按升序或降序)至少空一個(gè)位置存放要插入的數(shù)據(jù)烁落。插入元素后,仍然是按升序或降序排列
include<stdio.h> int main() { int arr[5]={10,9,12,8}; int i,j,k,temp; printf("插入一個(gè)數(shù):\n"); for(i=0;i<5;i++) if(arr[i]==0) scanf("%d",&arr[i]); for(k=0;k<5;k++) { for(j=0;j<5;j++) { if(arr[k]<arr[j]) { temp=arr[j]; arr[j]=arr[k]; arr[k]=temp; } } } for(i=0;i<5;i++) printf("%4d ",arr[i]); }
(3)互換數(shù)
include<stdio.h> int main() { int arr[5]; int i,temp; printf("請(qǐng)輸入五位數(shù):\n"); for(i=0;i<5;i++) scanf("%d",&arr[i]); temp=arr[0]; arr[0]=arr[4]; arr[4]=temp; temp=arr[1]; arr[1]=arr[3]; arr[3]=temp; for(i=0;i<5;i++) printf("%d\n",arr[i]); }
一豌注、數(shù)組
1伤塌、二維數(shù)組 行數(shù)可以省略,列不可以试C看稀! #include<stdio.h> int main() { //以下初始方法均可 int arr[][3]={1,2,3,4,5,6,7,8,9}; //int arr[3][3]={1,2,3,4,5,6,7,8,9}; //int arr[][3]={1,2,3,4,5}; //int arr[][3]={0}; //遍歷輸出二維數(shù)組 int i=0; int j=0; for(i=0;i<3;i++) { for(j=0;j<3;j++) { arr[i][j]=3*i+1; //或者手動(dòng)輸入 //scanf("%d",arr[i][j]); } } for(i=0;i<3;i++) { for(j=0;j<3;j++) { //printf("arr[%d][%d]=%d",i,j,arr[i][j]); printf("%4d",arr[i][j]); } printf("\n"); } }
求二維數(shù)組的總和余平均值
include<stdio.h> int main() { int arr[][3]={1,2,3,4,5,6,7,8,9}; int i,j,sum=0; float k=0; for(i=0;i<3;i++) for(j=0;j<3;j++) { sum=sum+arr[i][j]; } k=(float)sum/9; printf("sum=%d k=%f\n",sum,k); printf("===========================\n"); //每行 的總和即平均值 int sum1=0; float k1=0; //平均值 for(i=0;i<3;i++) { sum1=0; for(j=0;j<3;j++) { sum1=sum1+arr[i][j]; } k1=(float)sum1/3; printf("sum1=%d k1=%f\n",sum1,k1); } printf("===========================\n"); //每列 的總和即平均值 int sum2=0; float k2=0; //平均值 for(i=0;i<3;i++) { sum2=0; for(j=0;j<3;j++) { sum2=sum2+arr[j][i]; } k2=(float)sum2/3; printf("sum2=%d k2=%f\n",sum2,k2); } }
二齿风、指針
(1) 指針類型是一種特殊類型三種定義類型:DataType name;DataType name;DataType * name; *:是指針的標(biāo)志name: 變量名指針和普通變量的區(qū)別:指針:存地址普通變量:存值指針只能保存與其相同類型的地址int *p; 只能保存int 型地址char *pc; 只能保存char 型地址double *pd; 只能保存double 型地址
(2) 指針初始化
int *p=NULL; //ok
int a=3; //okint *pa=&a;
int *pb; //okpb=&a;
int ****pc; //這種賦值error *pc=&a;
include<stdio.h> int main() { int num=6; //NULL是一個(gè)空地址 是一個(gè)宏 int *pa=NULL; int *pb=# 把num 的地址賦給pb药薯, *號(hào)是取pb指向地址里面的值 int pc; pc=# int pb; //錯(cuò)誤 不能這樣賦值 pb=# 地址的訪問 //地址 printf("&num=%p\n",&num); printf("pb=%p\n",pb); //元素的訪問 printf("num=%d\n",num); //+pb是取地址的值 而pb里面是&num的地址, printf("pb=%d\n",pb); }
(3) 地址的訪問
int a=10; int pb; pb=&a; 變量名 變量地址 變量值 a 0x00012 10 pb 0x00024 0x000012 pb:取指針對(duì)應(yīng)內(nèi)存里面的值 可以把指針變量賦值給同類型指針 #include<stdio.h> int main() { int p=NULL; // printf("p=%p\n",p); //空地址不能訪問里面的值 // printf("p=%d\n",p);//error內(nèi)存泄漏 核心轉(zhuǎn)儲(chǔ) int a=10; int pa=&a; printf("&a=%p\n",&a); printf("p=%p\n",p); printf("&p=%p",&pa); printf("a=%d\n",a); printf("pa=%d\n",pa); } #include<stdio.h> int main() { int p=10; //error 不能將常量直接賦值給指針變量 printf("p=%p\n",p); printf("p=%d\n",p);//內(nèi)存中并未分配0xa這塊內(nèi)存 int a=12; int pa=&a; int pb; pb=pa; //可以把指針變量賦值給同類型指針 printf("pa=%p\n",pa); printf("pb=%p\n",pb); printf("pa=%d\n",pa); printf("pa=%d\n",*pa); //強(qiáng)制類型轉(zhuǎn)化 臨時(shí)轉(zhuǎn)化 并不改變pa的屬性 char pc=(char )pa; printf("pc=%d\n",pc); }
(4) 64位機(jī)下所有指針大小為8 32位機(jī)為4
一般情況寫4#include<stdio.h>int main(){ printf("sizeof(char *)=%ld\n",sizeof(char *)); printf("sizeof(short *)=%ld\n",sizeof(short *)); printf("sizeof(int *)=%ld\n",sizeof(int *)); printf("sizeof(long *)=%ld\n",sizeof(long *)); printf("sizeof(float *)=%ld\n",sizeof(float *)); printf("sizeof(double *)=%ld\n",sizeof(double *));}結(jié)果: sizeof(char *)=8 sizeof(short *)=8 sizeof(int *)=8 sizeof(long *)=8 sizeof(float *)=8 sizeof(double *)=8
(5) 指針的類型和指針?biāo)赶虻念愋蚷nt *pa;double pd;指針的類型: 是類型+ 如 int 指針?biāo)赶虻念愋?:就是類型 int一句話就是指針的類型int 指向的是int類型
二救斑、 指針與數(shù)組
(1) 數(shù)組名是一個(gè)地址 數(shù)組元素的訪問的方法: int arr[5]={1,2,3,4,5}; int *pa=arr; arr[0]; arr[3]; *(arr); (arr+3); (pa); (pa+3); pa[0]; pa[3]; #include<stdio.h> int main() { int arr[5]={1,2,3,4,5}; //數(shù)組名表示的是一個(gè)地址 int pa=arr; printf("===========================\n"); printf("arr=%p\n",arr); printf("&arr[0]=%p\n",&arr[0]); printf("pa=%p\n",pa); printf("===========================\n"); //地址是一樣的 printf("arr+1=%p\n",arr+1); printf("pa+1=%p\n",pa+1); //地址是一樣的 printf("===========================\n"); printf("arr+2=%p\n",arr+2); printf("pa+2=%p\n",pa+2); //地址里面的值是一樣的 printf("===========================\n"); printf("(arr+2)=%d\n",(arr+2)); printf("(pa+2)=%d\n",(pa+2)); } #include<stdio.h> int main() { int arr[5]={1,2,3,4,5}; //數(shù)組名表示的是一個(gè)地址 int *pa=arr; //數(shù)組元素的訪問 printf("arr[0]=%d\n",arr[0]); //指針對(duì)數(shù)組元素的訪問 printf("pa[0]=%d\n",pa[0]); printf("arr[4]=%d\n",arr[4]); printf("pa[4]=%d\n",pa[4]); } #include<stdio.h> int main() { char arr[16]={"hello,shanghai!"}; //數(shù)組名表示的是一個(gè)地址 char pc = arr; for(pc=arr;pc<arr+16;pc++) { if(pc>='a' && *pc<='z') *pc -= 32; } pc=arr; printf("%s\n",pc); }
(2) 野指針
沒有初始化童本,或者其指向的內(nèi)存被釋放, 而指針沒有被置空 危害:造成系統(tǒng)資源的浪費(fèi)脸候,容易造成未知的致命錯(cuò)誤 #include<stdio.h> int main() { int num = 10; int pa = # printf("pa=%d\n",pa); int pb; //error ,未經(jīng)初始化而使用穷娱,容易出現(xiàn)段錯(cuò)誤 printf("pb = %d\n",pb); }
(3) 指針地址的運(yùn)算
指針的自增和自減 自增:指針指向高地址方向 自減:指針指向低地值方向 #include<stdio.h> int main() { int arr[5]={1,2,3,4,5}; int *p = arr+3; printf("arr+3=%p\n",arr+3); printf("p=%p\n",p); p--; printf("p-- = %p\n",p); p++; printf("p++ = %p\n",p); } #include<stdio.h> int main() { int a=10; int b=34; int *pa=&a; int *pb=&b; //指針相減绑蔫,表示兩指針之間的距離 printf("pa-pb=%ld\n",pa-pb); //指針相加沒有意義 printf("pa+pb=%ld\n",pa+pb); }
1、兩個(gè)類型相同的指針相加毫無意義泵额。比如p1和p2都是類型為int的指針配深,雖然他們指向的內(nèi)存中保存了兩個(gè)int數(shù)N1和N2,但是這兩個(gè)數(shù)在內(nèi)存中可能挨著嫁盲,也可以能間隔很遠(yuǎn)篓叶,甚至有可能是一個(gè)地方。假設(shè)p1值也就是N1位置起始值為1234亡资,P2為2345,這個(gè)時(shí)候如果直接相加得到的數(shù)據(jù)3589有可能已經(jīng)超出了內(nèi)存最大值或者指向某個(gè)無意義的內(nèi)存地址向叉,所以指針相加沒有意義可言锥腻。正確的應(yīng)該是N1和N2相加才是合理的算數(shù)運(yùn)算。
2母谎、指針可以相減瘦黑,可以和立即數(shù)加或減,是有意義的奇唤,是允許的幸斥。比如我想知道N1和N2之間到底間隔了多少字節(jié)的內(nèi)存,兩者相減就相當(dāng)于尺子上兩個(gè)刻度相減咬扇,也就是長(zhǎng)度或者寬度了甲葬。另外,和立即數(shù)的加減主來快速尋址懈贺,比如我有一個(gè)數(shù)組经窖,起始指針為P0,如果數(shù)組保存的是一系列INT值那么 P0+2sizeof(int)得到的值就是第三個(gè)元素的所在位置的地址梭灿,也是一個(gè)指針画侣,是有意義的(因?yàn)椴煌恼Z(yǔ)言和系統(tǒng),int值每次所占的字節(jié)數(shù)可能不一致堡妒,所以使用sizeof函數(shù)去求得而不是直接加常規(guī)的4)配乱。
(3) 指針加減一個(gè)常量,表示地址往高字節(jié)或底字節(jié)方向移動(dòng)
常量值sizeof(對(duì)應(yīng)數(shù)據(jù)類型)個(gè)字節(jié) (4) 概念區(qū)分 int arr[3]; //數(shù)組大小為3皮迟,存放三個(gè)int型變量 int pb; //指針搬泥,棋類型為int 型 int arr[3]; //指針數(shù)組 具體是什么看后面的兩個(gè)字 int (pa)[3]; //首先是指針 后是數(shù)組 所以是 數(shù)組指針,又稱 行指針 #include<stdio.h> int main() { int arr[4]={1,2,3,4}; int buf[4]; int (pa)[4]; int i=0; for(i=0;i<4;i++) { buf[i]=&arr[i]; } pa=&arr; printf("%d\n",buf[2]); =3 printf("%d\n",(pa)[1]); =2 }
2.二級(jí)指針
DataType **PointorName; int a = 10; int *q = &a; int *p = &q; p=q; p=q=a; 定義一個(gè)指針伏尼, 或?qū)Φ刂愤M(jìn)行操作時(shí)佑钾, 一定要確定指針的指向 #include<stdio.h> int main() { int a=10; int p=&a; int pa=&p; printf("&a=%p\n",&a); printf("p=%p\n",p); printf("&p=%p\n",&p); printf("pa=%p\n",&pa); printf("p=%d\n",p); printf("pa=%d\n",pa)
自我評(píng)價(jià);今天講的指針的基本的知識(shí)烦粒,以及指針數(shù)組休溶,和數(shù)組指針的區(qū)別代赁;腦子里有點(diǎn)懵,還是要多看多做兽掰,從最大程度上去理解它芭碍,掌握要領(lǐng);大家要是有什么學(xué)習(xí)指針的方法孽尽,希望能夠多提些建議窖壕,感謝不盡;要多花功夫啊學(xué)習(xí)這門語(yǔ)言的靈魂部分杉女;