一、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将其连成一个圈子继续循环报数,直到只剩一个人