一、PTA實驗作業
題目1: 判斷回文字符串
1.本題提交列表
2.設計思路
定義字符指針 *q存放*s的地址,*p,*k
k存放s的首地址
定義整型變量count1、count2存放指針地址的偏移量
for q=s to *s!='\0'
count2++
s++;
end for
p存放k的首地址
while(count1<count2) 判斷回文
if(從頭部指針所指的內容不等於尾部指針所指的內容)
break
頭部指針遞增
尾部指針遞減
if(count1>=count2)
順利完成循環,是回文數
返回 true
else
返回false
3.代碼截圖
4.本題調試過程碰到問題及PTA提交列表情況說明
返回值加上了雙引號導致返回不再是一個值,而是字符
題目2: 使用函數實現字符串部分復制
1.本題提交列表
2.設計思路
int count存放從第幾位數開始復制的值
char *q存放*t的地址
for i=t to *q
count++
if(count的值大於等於m)
*s++=*q 復制字符
end for
遍歷*s
3.代碼截圖
4.遇到的問題
剛開始條件寫錯了導致死循環輸出錯誤
條件改正確后,最后遍歷指針的內容時將對象搞錯寫成了*t導致輸出原來的內容
題目3:求子串在母串中最后一次出現的地址
1.本題提交列表
2.設計思路
char *p,*q,*a為空指針
while(*s)
p指向s的首地址
q指向t的首地址
while(*q)
if(q指向的內容等於p指向的內容)
q地址向下移動
p地址向下移動
else break
if(q指向的內容為結束符)
a指向s的首地址
s地址向下個地址移動
3.代碼截圖
4.本題調試過程碰到問題及PTA提交列表情況說明
最后的s++放在if條件語句內,導致指針s指向的內容沒有變化,判斷的字符串永遠都是not found,將其放在if條件語句外面即可
二、截圖本周題目集的PTA最后排名
三、閱讀代碼
題目1:將所有數字字符向前移動
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
char *Fun(char *s);
int main()
{
char s[80];
printf("Please input: ");
scanf("%s",s);
printf("\nThe result is: %s\n",Fun(s));
}
char *Fun(char *s)
{
int i, j, k, n;
char *p, *t;
n=strlen(s)+1; /* 字符串的長度,包括結束符標志 */
t=new char[n];
p=s;
j=0; k=0;
for(i=0; i<n; i++)
{
if(isdigit(s[i])) /* 如果是數字 */
p[j++]=s[i];
else
t[k++]=s[i];
}
p[j]=t[k]='\0';
strcat(p,t);
return p;
}
我覺得課堂派這個程序的思路值得我學習,要是我,我會選擇遍歷數組,將數組的所有數字字符一個個前移,而它是通過一個isdigit函數判斷是否是數字,是的話存進一個新數組中,否則存進原來的數組,達到的分離的目的,最后使用strcat函數連接字符完成排序
題目2:將數字字符轉換成相應的數字
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int Fun(char *s)
{
int sum=0 ;
while(*s)
{
if(isdigit(*s)) /* if(*s>='0'&& *s<='9')*/
sum=sum+*s-'0';
s++;
}
return sum;
}
int main()
{
char s[81];
int sum;
printf("\nEnter a string:");
gets(s);
sum=Fun(s);
printf("\nThe result is: %d\n",sum);
}
我覺得這個轉換數字的思路值得我學習,遍歷數組找判斷是否為數字可以用isdigit函數,是的話取出來累加即可得到相應的數值
四、本周學習總結
1.自己總結本周學習內容
本周學習了指針、數組和地址間的關系,並學會了如何在編程中運用指針解決題目。指針指向數組的第一個元素,即首地址。在訪問內存方面,指針和數組幾乎是相同的,但是也有一些細微的區別:指針是以地址作為值的變量,而數組名的值是一個特殊的固定地址,可以把它看作常量指針,例如
int a[100],*p
p=a;
p=&a[0]
這兩句話是等價的。
數組和指針的關系如下
數組名作為函數的參數中,需要注意的是,數組的形參實際上是一個指針。當進行參數傳遞時,主函數傳遞的是數組的基地址,數組元素本身不被復制,例如
int sum(int a[],int n) //int a[]等價於int *a
{
int i,s=0;
for(i=0;i<n;i++)
s+=a[i];
return s;
}
字符串和字符指針
如果定義一個字符指針接收字符串常量的值,該指針指向字符串的首字符,例如
char s[]="array";
char *sp="point";
printf("%s",sa);
printf("%s",sp);
printf("%s\n","string");
輸出結果如下
指針未賦值的危害
未賦值
賦值后
Tips:為了盡量避免引用未賦值的指針所造成的危害,在定義指針的時候,可先將它的初值置為空,如char *s=NULL;
string.h的常用庫函數,放在這方便以后復習和查找
函數名: strcpy
功 能: 拷貝一個字符串到另一個
用 法: char *strcpy(char *destin, char *source);
#include <stdio.h>
#include <string.h>
int main(void)
{
char string[10];
char *str1 = "abcdefghi";
strcpy(string, str1);
printf("%s\n", string);
return 0;
}
函數名:strncpy
原型:char * strncpy(char *dest, char *src, size_t n);
功能:將字符串src中最多n個字符復制到字符數組dest中(它並不像strcpy一樣遇到NULL才停止復制,而是等湊夠n個字符才開始復制),返回指向dest的指針。
#include <stdio.h>
#include <string.h>
int main(void)
{
char string[10];
char *str1 = "abcdefghi";
strncpy(string, str1,3);
printf("%s\n", string);
return 0;
}
函數名: strcat
功 能: 字符串拼接函數
用 法: char *strcat(char *destin, char *source);
#include <string.h>
#include <stdio.h>
int main(void)
{
char destination[25];
char *blank = " ", *c = "C++", *Borland = "Borland";
strcpy(destination, Borland);
strcat(destination, blank);
strcat(destination, c);
printf("%s\n", destination);
return 0;
}
函數名: strchr
功 能: 在一個串中查找給定字符的第一個匹配之處
用 法: char *strchr(char *str, char c);
#include <string.h>
#include <stdio.h>
int main(void)
{
char string[15];
char *ptr, c = 'r';
strcpy(string, "This is a string");
ptr = strchr(string, c);
if (ptr)
printf("The character %c is at position: %d\n", c, ptr-string);
else
printf("The character was not found\n");
return 0;
}
函數名: strcmp
功 能: 串比較
用 法: int strcmp(char *str1, char *str2);
看Asic碼,str1>str2,返回值 > 0;兩串相等,返回0
#include <string.h>
#include <stdio.h>
int main(void)
{
char *buf1 = "aaa", *buf2 = "bbb", *buf3 = "ccc";
int ptr;
ptr = strcmp(buf2, buf1);
if(ptr > 0)
printf("buffer 2 is greater than buffer 1\n");
else
printf("buffer 2 is less than buffer 1\n");
ptr = strcmp(buf2, buf3);
if (ptr > 0)
printf("buffer 2 is greater than buffer 3\n");
else
printf("buffer 2 is less than buffer 3\n");
return 0;
}
函數名: strnicmp
功 能: 將一個串中的一部分與另一個串比較, 不管大小寫
用 法: int strnicmp(char *str1, char *str2, unsigned maxlen);
#include <string.h>
#include <stdio.h>
int main(void)
{
char *buf1 = "BBB", *buf2 = "bbb";
int ptr;
ptr = strnicmp(buf2, buf1);
if (ptr > 0)
printf("buffer 2 is greater than buffer 1\n");
if (ptr < 0)
printf("buffer 2 is less than buffer 1\n");
if (ptr == 0)
printf("buffer 2 equals buffer 1\n");
return 0;
}
函數名:strlen
功能: strlen函數求的是字符串的長度,它求得方法是從字符串的首地址開始到遇到第一個'\0'停止計數,如果你只定義沒有給它賦初值,這個結果是不定的,它會從字符串首地址一直記下去,直到遇到'\0'才會停止。
size_t strlen(const char *s);
#include<stdio.h>
#include <string.h>
int main()
{
int i=0;
char *he ="Hello,world";
i=strlen(he);
printf("字符串長度為%d\n",i);
return 0;
}
函數名: strcspn
功 能: 在串中查找第一個給定字符集內容的段
用 法: int strcspn(char *str1, char *str2);
#include <stdio.h>
#include <string.h>
#include <alloc.h>
int main(void)
{
char *string1 = "1234567890";
char *string2 = "747DC8";
int length;
length = strcspn(string1, string2);
printf("Character where strings intersect is at position %d\n", length);
return 0;
}
函數名: strdup
功 能: 將串拷貝到新建的位置處
用 法: char *strdup(char *str);
#include <stdio.h>
#include <string.h>
#include <alloc.h>
int main(void)
{
char *dup_str, *string = "abcde";
dup_str = strdup(string);
printf("%s\n", dup_str);
free(dup_str);
return 0;
}
函數名:stricmp
功 能: 以大小寫不敏感方式比較兩個串
用 法: int stricmp(char *str1, char *str2);
#include <string.h>
#include <stdio.h>
int main(void)
{
char *buf1 = "BBB", *buf2 = "bbb";
int ptr;
ptr = stricmp(buf2, buf1);
if (ptr > 0)
printf("buffer 2 is greater than buffer 1\n");
if (ptr < 0)
printf("buffer 2 is less than buffer 1\n");
if (ptr == 0)
printf("buffer 2 equals buffer 1\n");
return 0;
}
函數名: strerror
功 能: 返回指向錯誤信息字符串的指針
用 法: char *strerror(int errnum);
#include <stdio.h>
#include <errno.h>
int main(void)
{
char *buffer;
buffer = strerror(errno);
printf("Error: %s\n", buffer);
return 0;
}
函數名: strcmpi
功 能: 將一個串與另一個比較, 不管大小寫
用 法: int strcmpi(char *str1, char *str2);
#include <string.h>
#include <stdio.h>
int main(void)
{
char *buf1 = "BBB", *buf2 = "bbb";
int ptr;
ptr = strcmpi(buf2, buf1);
if (ptr > 0)
printf("buffer 2 is greater than buffer 1\n");
if (ptr < 0)
printf("buffer 2 is less than buffer 1\n");
if (ptr == 0)
printf("buffer 2 equals buffer 1\n");
return 0;
}
函數名: strnicmp
功 能: 不注重大小寫地比較兩個串
用 法: int strnicmp(char *str1, char *str2, unsigned maxlen);
#include <string.h>
#include <stdio.h>
int main(void)
{
char *buf1 = "BBBccc", *buf2 = "bbbccc";
int ptr;
ptr = strnicmp(buf2, buf1, 3);
if (ptr > 0)
printf("buffer 2 is greater than buffer 1\n");
if (ptr < 0)
printf("buffer 2 is less than buffer 1\n");
if (ptr == 0)
printf("buffer 2 equals buffer 1\n");
return 0;
}
函數名: strnset
功 能: 將一個字符串前n個字符都設為指定字符
用 法: char *strnset(char *str, char ch, unsigned n);
#include <stdio.h>
#include <string.h>
int main(void)
{
char *string = "abcdefghijklmnopqrstuvwxyz";
char letter = 'x';
printf("string before strnset: %s\n", string);
strnset(string, letter, 13);
printf("string after strnset: %s\n", string);
return 0;
}
函數名: strpbrk
功 能: 在串中查找給定字符集中的字符
用 法: char *strpbrk(char *str1, char *str2);
#include <stdio.h>
#include <string.h>
int main(void)
{
char *string1 = "abcdefghijklmnopqrstuvwxyz";
char *string2 = "onm";
char *ptr;
ptr = strpbrk(string1, string2);
if (ptr)
printf("strpbrk found first character: %c\n", *ptr);
else
printf("strpbrk didn't find character in set\n");
return 0;
}
函數名: strrchr
功 能: 在串中查找指定字符的最后一個出現
用 法: char *strrchr(char *str, char c);
#include <string.h>
#include <stdio.h>
int main(void)
{
char string[15];
char *ptr, c = 'r';
strcpy(string, "This is a string");
ptr = strrchr(string, c);
if (ptr)
printf("The character %c is at position: %d\n", c, ptr-string);
else
printf("The character was not found\n");
return 0;
}
函數名: strrev
功 能: 串倒轉
用 法: char *strrev(char *str);
#include <string.h>
#include <stdio.h>
int main(void)
{
char *forward = "string";
printf("Before strrev(): %s\n", forward);
strrev(forward);
printf("After strrev(): %s\n", forward);
return 0;
}
函數名: strset
功 能: 將一個串中的所有字符都設為指定字符
用 法: char *strset(char *str, char c);
#include <stdio.h>
#include <string.h>
int main(void)
{
char string[10] = "123456789";
char symbol = 'c';
printf("Before strset(): %s\n", string);
strset(string, symbol);
printf("After strset(): %s\n", string);
return 0;
}
函數名: strstr
功 能: 在串中查找指定字符串的第一次出現
用 法: char *strstr(char *str1, char *str2);
#include <stdio.h>
#include <string.h>
int main(void)
{
char *str1 = "Borland International", *str2 = "nation", *ptr;
ptr = strstr(str1, str2);
printf("The substring is: %s\n", ptr);
return 0;
}
函數名: strtod
功 能: 將字符串轉換為double型值
用 法: double strtod(char *str, char **endptr);
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char input[80], *endptr;
double value;
printf("Enter a floating point number:");
gets(input);
value = strtod(input, &endptr);
printf("The string is %s the number is %lf\n", input, value);
return 0;
}
函數名: strtok
功 能: 查找由在第二個串中指定的分界符分隔開的單詞
用 法: char *strtok(char *str1, char *str2);
#include <string.h>
#include <stdio.h>
int main(void)
{
char input[16] = "abc,d";
char *p;
p = strtok(input, ",");
if (p) printf("%s\n", p);
p = strtok(NULL, ",");
if (p) printf("%s\n", p);
return 0;
}
函數名: strtol
功 能: 將串轉換為長整數
用 法: long strtol(char *str, char **endptr, int base);
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *string = "87654321", *endptr;
long lnumber;
lnumber = strtol(string, &endptr, 10);
printf("string = %s long = %ld\n", string, lnumber);
return 0;
}
函數名:strupr
功 能: 將串中的小寫字母轉換為大寫字母
用 法: char *strupr(char *str);
#include <stdio.h>
#include <string.h>
int main(void)
{
char string[ ] = "abcdefghijklmnopqrstuvwxyz", *ptr;
ptr = strupr(string);
printf("%s\n", ptr);
return 0;
}
函數名: swab
功 能: 交換字節
用 法: void swab (char *from, char *to, int nbytes);
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char source[15] = "rFna koBlrna d";
char target[15];
int main(void)
{
swab(source, target, strlen(source));
printf("This is target: %s\n", target);
return 0;
}
2.羅列本周一些錯題
D選擇中的a++為非法表示,地址不能自增
運算符優先級中,+的優先級比&高,所以p=&a[0]+1等價於p=&a[1],其值就為3
PTA指針 6-11報數
void CountOff( int n, int m, int out[] )
{
int i=0,j=0,k=0,count=0,a[MAXN];
for(i=0;i<n;i++)
a[i] = i+1;
i=0;
while(count < n)
{
if(a[i]!=0)
k++;
if(k==m)
{
j++;
out[i]=j;
k=0;
count++;
a[i]=0;
}
i++;
if(i==n)
i=0;
}
}
當時自己在做的時候沒有思路,去網上查找看別人的思路,發現了這個思路很簡單,沒有我想象的那么復雜。
首先對每個人進行順序編號,然后開始報數,報到m的人退出圈子並且用數組記錄其編號,當數組報到n時,初始化i=0將其連成一個圈子繼續循環報數,直到只剩一個人