C博客做業05--指針

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定義類型的別名,能夠減小錯誤的發生,並且直觀簡潔。
相關文章
相關標籤/搜索