c語言 基礎第四天

作業整理;

指針的基本的結構與基礎知識整理;


作業講解:
(1) 將2~100之間的素數 保存到數組中,并遍歷輸出,每五行一個

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整除的數, //若找到則跳出內層循環 if(i%j==0) break; } //若i==j,則i是素數,否則不是 if(i==j) { arr[k]=i; k++; printf("%4d",i); if(k%5==0) printf("\n"); } } }

(2) 在一個升序或降序排列的數組中,插入一個元素;提示:數組元素部分初始化
(按升序或降序)至少空一個位置存放要插入的數據。插入元素后,仍然是按升序或降序排列

include<stdio.h> int main() { int arr[5]={10,9,12,8}; int i,j,k,temp; printf("插入一個數:\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)互換數

include<stdio.h> int main() { int arr[5]; int i,temp; printf("請輸入五位數:\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]); }

一、數組
1、二維數組 行數可以省略,列不可以省!! #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}; //遍歷輸出二維數組 int i=0; int j=0; for(i=0;i<3;i++) { for(j=0;j<3;j++) { arr[i][j]=3*i+1; //或者手動輸入 //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"); } }

求二維數組的總和余平均值

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; *:是指針的標志name: 變量名指針和普通變量的區別:指針:存地址普通變量:存值指針只能保存與其相同類型的地址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是一個空地址 是一個宏 int *pa=NULL; int *pb=# 把num 的地址賦給pb, *號是取pb指向地址里面的值 int pc; pc=# int pb; //錯誤 不能這樣賦值 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:取指針對應內存里面的值 可以把指針變量賦值給同類型指針 #include<stdio.h> int main() { int p=NULL; // printf("p=%p\n",p); //空地址不能訪問里面的值 // printf("p=%d\n",p);//error內存泄漏 核心轉儲 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);//內存中并未分配0xa這塊內存 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); //強制類型轉化 臨時轉化 并不改變pa的屬性 char pc=(char )pa; printf("pc=%d\n",pc); }

(4) 64位機下所有指針大小為8 32位機為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 *));}結果: sizeof(char *)=8 sizeof(short *)=8 sizeof(int *)=8 sizeof(long *)=8 sizeof(float *)=8 sizeof(double *)=8

(5) 指針的類型和指針所指向的類型int *pa;double pd;指針的類型: 是類型+ 如 int 指針所指向的類型 :就是類型 int一句話就是指針的類型int 指向的是int類型
二、 指針與數組
(1) 數組名是一個地址 數組元素的訪問的方法: 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}; //數組名表示的是一個地址 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}; //數組名表示的是一個地址 int *pa=arr; //數組元素的訪問 printf("arr[0]=%d\n",arr[0]); //指針對數組元素的訪問 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!"}; //數組名表示的是一個地址 char pc = arr; for(pc=arr;pc<arr+16;pc++) { if(pc>='a' && *pc<='z') *pc -= 32; } pc=arr; printf("%s\n",pc); }

(2) 野指針
沒有初始化,或者其指向的內存被釋放, 而指針沒有被置空 危害:造成系統資源的浪費,容易造成未知的致命錯誤 #include<stdio.h> int main() { int num = 10; int pa = # printf("pa=%d\n",pa); int pb; //error ,未經初始化而使用,容易出現段錯誤 printf("pb = %d\n",pb); }

(3) 指針地址的運算
指針的自增和自減 自增:指針指向高地址方向 自減:指針指向低地值方向 #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、兩個類型相同的指針相加毫無意義。比如p1和p2都是類型為int的指針,雖然他們指向的內存中保存了兩個int數N1和N2,但是這兩個數在內存中可能挨著,也可以能間隔很遠,甚至有可能是一個地方。假設p1值也就是N1位置起始值為1234,P2為2345,這個時候如果直接相加得到的數據3589有可能已經超出了內存最大值或者指向某個無意義的內存地址,所以指針相加沒有意義可言。正確的應該是N1和N2相加才是合理的算數運算。
2、指針可以相減,可以和立即數加或減,是有意義的,是允許的。比如我想知道N1和N2之間到底間隔了多少字節的內存,兩者相減就相當于尺子上兩個刻度相減,也就是長度或者寬度了。另外,和立即數的加減主來快速尋址,比如我有一個數組,起始指針為P0,如果數組保存的是一系列INT值那么 P0+2sizeof(int)得到的值就是第三個元素的所在位置的地址,也是一個指針,是有意義的(因為不同的語言和系統,int值每次所占的字節數可能不一致,所以使用sizeof函數去求得而不是直接加常規的4)。
(3) 指針加減一個常量,表示地址往高字節或底字節方向移動
常量值
sizeof(對應數據類型)個字節 (4) 概念區分 int arr[3]; //數組大小為3,存放三個int型變量 int pb; //指針,棋類型為int 型 int arr[3]; //指針數組 具體是什么看后面的兩個字 int (pa)[3]; //首先是指針 后是數組 所以是 數組指針,又稱 行指針 #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.二級指針
DataType **PointorName; int a = 10; int *q = &a; int *p = &q; p=q; p=q=a; 定義一個指針, 或對地址進行操作時, 一定要確定指針的指向 #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)

自我評價;今天講的指針的基本的知識,以及指針數組,和數組指針的區別;腦子里有點懵,還是要多看多做,從最大程度上去理解它,掌握要領;大家要是有什么學習指針的方法,希望能夠多提些建議,感謝不盡;要多花功夫啊學習這門語言的靈魂部分;

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容