0.展現PTA總分
1.本章學習總結
1.1學習內容總結
指針變量的定義
類型名: *指針變量名 例如: int *p;//定義一個整型變量p,指向整型變量;
指針和數組的賦值與初始化
通常狀況下,數組的地址不能修改,內容能夠修改;而指針的內容能夠修改,指針指向的內容也能夠修改,但這以前要爲指針初始化。 如: int p[5]; p=p+1; //錯誤 p[0]=1; //正確 int *p; p=p+1; //正確 p[0]=1;//錯誤,指針沒有初始化; // int i; int *p=&i; p[0]=1;//正確 對於字符指針還有比較特殊的狀況。 如: char * p="abc"; p[0]='d';//錯誤
指針作循環變量作法
例如:對數組元素求和 int a[100]; int *p; int sum=0; p=a; for(p=a;p<=&a[99];p++) { sum+=*p; } 在循環中,指針變量p的初值是數組a的基地址,P連續取值&a[0],&a[1],…&a[99]。
字符串指針如何表示字符串
- 對指向字符變量的指針變量應賦予該字符變量的地址。
例如: char c, *p=&c;//表示p是一個指向字符變量c的指針變量。 char *s="apple";//表示s是一個指向字符串的指針變量。把字符串的首地址賦予s。
- 用字符串指針指向一個字符串。 例如:
#include <stdio.h> int main(){ char *string = "I love China!"; printf("%s\n", string); return 0; }
動態內存分配
- (1)函數malloc()
原型:void* malloc(unsigned size); 1.在內存的動態存儲區中分配一塊長度爲size字節的連續區域,參數size爲須要內存空間的長度,若申請成功,則返回指向所分配內存空間的起始地址的指針;若申請不成功,則返回NULL. 2.函數malloc不能初始化所分配的內存空間,而函數calloc能.若是由malloc()函數分配的內存空間原來沒有被使用過,則其中的每一位可能都是0;反之, 若是3.這部份內存曾經被分配過,則其中可能遺留有各類各樣的數據. 調用函數malloc()時,應該利用sizeof計算儲存塊的大小,不能直接寫數值,由於不一樣平臺數據類型佔用空間大小可能不一樣。
- (2)函數calloc()
1.原型:void* calloc(size_t n, size_t size); 2.參數size爲申請地址的單位元素長度,n爲元素個數,即在內存中申請n*size字節大小的連續地址空間. 3.函數calloc()在內存的動態儲存區中分配n個連續空間,每個儲存空間的長度爲size, 並將所分配的內存空間中的每一位都初始化爲零,若是是字符類型或整數類型的元素分配內存,那麼這些元素將保證會被初始化爲0;若是是爲指針類型的元素分配內存,那麼這些元素一般會被初始化爲空指針;若是是實型數據分配內存,則這些元素會被初始化爲浮點型的零.
- (3)函數free()
1.原型:void free(void *ptr); 2.釋放以後由動態儲存分配函數申請的整塊內存空間,ptr爲指向要釋放空間的首地址。free以後,申請內存的那個指針就會變成野指針,爲避免出現野指針錯誤, 儘可能在操做以後將指針置爲NULL 3.注意:申請和釋放是一塊兒的,因此程序是不能進行屢次free同一個指針,不然程序會出錯。釋放以後不能夠再經過該指針去訪問已經釋放的塊,不然可能引發災難性的錯誤
指針數組及其應用
-
很是容易混淆的兩個概念:「指針數組」與「數組指針」 指針數組:表示的是一個數組,數組中每個變量都是指針型變量; 數組指針:表示的是一個指針類型的變量,這個指針變量指向的是一個數組。數組
-
數組指針
定義int (*)data[10] = NULL;//定義了一個指向長度爲10的int數組(int [10])的指針.
app -
指針數組:
定義 int *p[n];
[]優先級高,先與p結合成爲一個數組,數組名爲p,該p數組中有n個元素,分別爲p[0]、p[1]、……、p[n-1],每一個元素均爲指向int類型的指針變量(即(int *) p[n]),即元素的值爲地址。函數
指針數組應用: 例:查找奧運五環色的位置,用指針數組實現 #include<stdio.h> #include<string.h> int main() { int i; char *color[5]={"red","blue","green","black","yellow"}; char str[20]; scanf("%s",str); for(i=0;i<5;i++) if(strcmp(str,color[i])==0) break; if(i<5) printf("position:%d\n",i+1); else printf("Not Found\n"); return 0; }
二級指針、行指針
- 二級指針
定義:類型名 **變量名; 例如: int a=10; int *p=&a; int **pp=&p; 一級指針p指向整型變量a,二級指針pp指向一級指針p。因爲p指向a,因此p和&a的值同樣,a和*p表明同一個單元;因爲pp指向p,因此pp和&p的值同樣,pp和**p表明同一個單元
- 行指針
定義:int (*p)[3]; *(p+i);//即a[i],第i行數組名,指向第i行0列的int型元素 *(p+i)+j;//指向第i行j列的int型元素 *(*(p+i)+j);//取出第i行j列的內容
函數返回值爲指針
- 使用指針做爲函數參數返回多個值的示例
-運行結果
1.2本章學習體會
- 本章學習了指針,包括數組指針,指針數組,字符指針,一級、二級指針等重要內容,內容不少,相對來講也比較難,知識點抽象不易理解,作題無從下手。可是指針是學習C語言最重要的部分,務必要掌握,不能急躁,先理解它的概念,以後熟悉它的格式以及使用方法,多打代碼練習。
- 代碼量有1000以上。
2.PTA實驗做業
2.1題目7-2 藏尾詩
2.1.1僞代碼
for i=0 to N 輸入字符串 動態分配:p[i]=(char*)malloc(sizeof(str)+1) 將輸入的字符串複製到p[i] end for for i=0 to N 求字符數組p[i]的長度 輸出最後一個字組成的字符串 end for
2.1.2代碼截圖
2.1.3總結本題知識點
動態分配:p[i]=(char*)malloc(sizeof(str)+1) 將輸入的字符串複製到p[i]:strcpy(p[i],str) 求字符數組p[i]的長度:len=strlen(p[i])+1 輸出最後一個字組成的字符串:printf("%s",p[i]+len-2)
2.1.4PTA提交列表及說明
答案錯誤:一開始用fgets輸入字符串,後來改成用fets輸入,仍是答案錯誤。 答案錯誤:輸出字符串的時候沒有減去2。 格式錯誤:剛開始用puts循環輸出 答案錯誤:改成用printf循環輸出,寫成了%c答案錯誤,再改成%s 格式錯誤:在printf()裏面加上了\n
2.2題目6-10 填充矩陣
2.2.1僞代碼
for i=0 to n for j=0 to n if(是副對角線上的元素) *(p[i]+j=1; end if if(是副對角線下方的元素) *(p[i]+j=2; end if if(是副對角線上方的元素) *(p[i]+j=3; end if end for end for
2.2.2代碼截圖
2.2.3總結本題知識點
副對角線上的元素:(i+j)==n-1 副對角線下方的元素:(i+j)>n-1 副對角線上方的元素:(i+j)<n-1 取出第i行j列的內容:*(p[i]+j)
2.2.4PTA提交列表及說明
運行超時:不知道哪裏錯了,試試在每一個if語句後面加個break,仍是同樣的結果。 運行超時:一開始寫的是*(*(p+i)+j),後來發現能夠改爲*(p[i]+j)。 運行超時:找了好久發現if語句裏面i+j沒有加上括號,改爲if((i+j)==n-1) 答案錯誤:副對角線上方下方的元素是2仍是3搞混了 答案錯誤:寫成了(i+j)==n,運行發現1都不在副對角線上,就改爲(i+j)==n-1
2.3題目6-6 查找子串
2.3.1僞代碼
i=0,j=1; while(s[i]) if(在字符串中找到子串的第一個字符) while(s[i+j]==t[j]&&t[j]!='\0') j++; end while if(t[j]=='\0') 返回返回子串t在s中的首地址 end if end if i++; end while
2.3.2代碼截圖
2.3.3總結本題知識點
若是在字符串中找到子串的第一個字符,則開始從當前位置掃描子串 if(s[i]==t[0] { while(s[i+j]==t[j]&&t[j]!='\0') j++; } 返回子串t在s中的首地址:return s+i;
2.3.4PTA提交列表及說明
部分正確:搞不清楚j是從0開始仍是從1開始。 部分正確:錯誤寫成當t[j]不等於0時返回子串t在s中的首地址。 部分正確:不知道t在s中的首地址怎麼表示。
3.閱讀代碼
- 代碼功能:計算比賽中問題的最大指望值,並能實現找出字典上最小的序列,使預期數目的解決問題最大。
- 代碼優勢: 使用using namespace std調用命名空間std內定義的全部標識符,這樣能夠在不一樣命名空間裏,起一樣的變量名,防止變量名用盡或者衝突。 調用多個頭文件,賦予了調用某些函數的權限,便於進行類型檢查,增長程序可讀性。 使用屢次宏定義,實現了一些簡單的函數功能,提高了程序編寫的靈活性。 使用typedef定義類型的別名,能夠減小錯誤的發生,並且直觀簡潔。