C博客作业05--指针
0.展示PTA总分
1.本章学习总结
1.1学习内容总结
1.1.1指针大概
-
①专门用来存放变量地址的变量称为“指针变量”,简称为指针。
-
②指针变量的定义:类型名 *指针变量名; 如 int *p;
-
③在定义指针变量时,指针声明符不是指针的组成部分,如 intp; 表示p是指针变量,不是p。
-
④指针类型的变量是它所指的变量的数据类型,不同类型的指针变量所占的内存空间是大小相同。
-
⑤定义完指针变量后要先赋值再使用,如果没有被赋值,它将指向一个不确定的单元,即野指针。
-
⑥指针变量的赋值:如 p = &i; 或 p = 0; 或 p = NULL; 或 p = (int*)1732; 但不能将其他数值作为指针变量的初值。
-
⑦ p = 0; 或 p = NULL表示空指针,空指针不指向任何单元。
1.1.2指针的基本运算
-
①相同类型的指针能进行赋值、比较和算术运算。
-
②两个指针不能相加,但可以相减,二者的差值表示二者相隔的存储单元。
-
③在完成定义后,*表示间接访问运算符,用于访问指针所指向的变量。
-
④如 p=p+1、++p 和 (p)++ 都是将指针所指向变量的值加一;而p++等价于(p++) 表示先取*p的值作为表达式的值,再将指针p的值加一。
1.1.3指针作为函数的参数
-
①调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指向的变量的值。
-
②在函数定义时将指针作为指针作为形参,在函数调用时将变量的地址作为实参。
-
③将指针作为函数的参数就能使函数返回多个值。
1.1.4指针、数组和地址
-
①数组的基地址是数组中第一个元素(下标为0)的地址,所以数组名本身是一个地址即指针值。
-
②在访问内存方面,指针和数组几乎相同,如 p=a; 等价于 p=&a[0]; *(a+i)等价于a[i]。
-
③数组与指针的区别:指针是以地址作为值的变量,而数组名的值是一个特殊的固定地址,即指针常量,所以a=p是非法的。
-
④p为指针a为数组,p=a+1是合法的,a=a+1是非法的,a+i是合法的,a++是非法的。
-
⑤设p和q是指向数组元素的指针,则p-q产生一个int型的值,该值表示在p和q之间的数组元素的个数。
-
⑥当指针指向数组,指针加1或减1时,并非指针的值加1或减1,而是加上或减去该指针所指向的那个变量数据类型的长度,即所占的字节数。如p指向a[1],设用2个字节存储整型数据,且a[1]的地址为2004,则p--后,p的值为2002,即a[0]的地址。
1.1.5字符指针
-
①调用printf()函数,以%s的格式输出字符串(直到遇见'\0'为止),作为输出参数,数组名、指针和字符串的值都是地址。如:
printf("%s",sa+2); //以数组元素sa[2]的地址作为输出参数
printf("%s",sp+3); //以sp+3作为起始地址
printf("%s",“string”); //输出string -
②字符指针与字符数组的不同:字符指针存储字符串首字符的地址,而字符数组的每个元素防一个字符,字符串就存放在数组中。
1.1.6用指针实现内存动态分配
-
①动态存储分配函数malloc()
功能:在内存的动态存储区中分配一连续空间,其长度为size。若申请成功,返回指向分配内存空间的起始地址的指针;若不成功,返回NULL。 -
②计数动态存储分配函数calloc()
功能:在内存的动态存储区中分配n个连续空间,每一存储空间的长度为size,并把内容全初始化为0。若申请成功,返回指向分配内存空间的起始地址的指针;若不成功,返回NULL。 -
③动态存储释放函数free()
功能:释放由动态存储分配函数申请到的整块内存空间,在某个动态分配的存储块不再用时,应及时将它释放,该函数无返回值。 -
④分配调整函数realloc()
功能:更改以前的存储分配,
1.1.7指针数组
-
①一维指针数组定义格式:类型名 *数组名 [数组长度];
-
②数组的元素类型是字符指针,用于存放字符数据单元的地址。
如:printf("%x",color[i]); //以16进制的方式输出color[i]所指向的字符串的首地址。 -
③对指针数组元素的操作与对同类型指针变量的操作相同。
1.1.7二级指针
-
①二级指针定义:类型名**变量名;
-
②
定义int a=10; int p=&a; int **pp=&p
p指向a,p与&a的值一样,a与p代表同一个单元
pp指向p,pp与&p的值一样,p与pp代表同一个单元
&&a、&&p和pp等价,&a、p和pp等价,a、*p和**pp代表同一单元。
1.1.8二维数组的指针形式
- ①int a[3][4];
名 | 说明 |
---|---|
a | 二维数组名是一个二级指针,即a[0]的地址 |
a[0] | 一级指针,即a[0][0]的地址 |
a+i | 第i行的地址 |
*(a+i) | 第i行首元素的地址,等价于a[i] |
**(a+i) | 第i行首元素的值 |
- ②虽然a、a的值相同,但含义不同。a是行元素数组的首地址,又称行地址,是二级指针。而a是首行第一个元素的地址,又称列地址,是一级指针。
*1.2本章学习体会
1.2.1学习感受
指针这块内容确实比较难理解,我PTA上的大多数题目都是用数组的操作思维完成的,现在通过博客重新过了一遍书本的内容,发现指针在一些方面确实有它独特的优势,一定要好好学。
1.2.2代码量
代码量大约394行。
2.PTA实验作业
2.1计算最长的字符串长度
2.1.1伪代码
int max_len(char* s[], int n)
{
设i用于循环,设len表示各个字符串的长度,设max表示最长长度并赋初值0
for i = 0 to i<n
len记录各个字符串长度
if (len > max) //比较当前字符串长度与之前的最长长度
发现更长的,就赋值给max
end if
end for
返回max
}
2.1.2代码截图
2.1.3造测试数据
输入数据 | 输出数据 | 说明 |
---|---|---|
4换行blue换行yellow换行red换行green | 6 | 正常数据 |
3换行ccc换行ccc换行ccc | 3 | 有重复数据时,程序仍正常 |
0 | 0 | 仅输入0时,输出max的初值 |
-1 | 0 | 输入负数时,输出max的初值 |
11换行a换行a换行a换行a换行a换行a换行a换行a换行a换行a换行aa | 2 | 超过10组数据且最长数据在最后,程序的结果虽然正确,但VS有溢出报错 |
2换行g换行jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj | 无 | 程序炸了,第二组数据溢出,VS报错 |
a | 0 | 程序炸了,通过设printf显示输入的a被转换成了-858993460,使程序输出max的初值 |
2.1.4PTA提交列表及说明
-
Q1:答案错误
-
A1:没仔细审题,没看见#include <string.h> 于是用了sizeof计算各个字符串的长度,测试时,一直输出4,后来查了资料才知道sizeof用来求分配给某某的内存空间大小的,而指针一般分配4字节,
于是结果就是4,改用strlen就全通过了。
2.2藏尾诗
2.2.1伪代码
main函数
设i、k用于循环,定义poem数组存放诗,定义end数组存放尾字
for i = 0 to i < 4
输入每行的数据
将倒数第二个有意义字符放入end数组中
将倒数第一个有意义字符放入end数组中
end for
end[8] = 0;
输出end数组
2.2.2代码截图
2.2.3造测试数据
输入数据 | 输出数据 | 说明 |
---|---|---|
悠悠田园风\n然而心难平\n兰花轻涌浪\n兰香愈幽静 | 风平浪静 | 正常数据 |
悠悠田园风\n然而心难平\n兰花轻涌浪\n兰香 | 风平浪香 | 每行长短不一,程序正常运行 |
悠悠田园风\n然而心难平\n兰花轻涌浪 | 风烫平浪 | 缺一句的数据,由于第二行数据是换行,因此程序在生成第二个数据时会以乱码处理 |
2.2.4PTA提交列表及说明
-
Q1:运行时错误
-
A1:忘了一个汉字占两个字节,在定义表示尾字的数组时长度给小了,在扩大数组长度后就通过了。
2.3说反话-加强版
2.3.1伪代码
main函数
定义i、j用于循环,定义len表示字符串长度,定义woerdLen表示各个单词长度
定义flagFirst用于判断是否为句首,定义str数组用于存储字符串
输入字符串
计算字符串长度并处理
for i = len to 0
if 发现单词
记录单词长度
else if 一个单词记录完毕
if 句尾第一个词
flagFirst为0
else
输出空格
end if
输出单词
end for
单词长度清零
end if
end for
if flagFirst为0 //句首为空格
if 单词长度大于0
输出空格
输出单词
end if
else //句首不为空格
if 单词长度大于0
输出单词
end if
end if
2.3.2代码截图
2.3.3造测试数据
输入数据 | 输出数据 | 说明 |
---|---|---|
Hello World Here I | I Here World Hello | 中有多个空格,正常输出 |
Hello World Here I | I Here World Hello | 句首有多个空格,正常输出 |
Hello World Here I | I Here World Hello | 句尾有多个空格,正常输出 |
a | a | 最小词且前有空格,正常输出 |
aa | aa | 一词且后有空格,正常输出 |
苏卡 不列 | 不列 苏卡 | 有汉字,正常输出 |
无 | 全空格,无输出 | |
换行 | 无 | 直接退出程序 |
2.3.4PTA提交列表及说明
-
Q1:部分正确
-
A1:存在格式错误问题,经检查,发现我的程序中在输出单词后会自动补充一个空格,于是决定删去此功能,增加判断语句。
-
Q2:部分正确
-
A2:“一个词,末尾有空格”测试点显示答案错误,如输入“aa ”时,程序无输出,经检查,发现我的判断语句未能识别该类情况,再次对判断语句进行完善补充。
-
Q3:编译错误
-
A3:拼写错误,纠正后就全通过了。
3.阅读代码
-
代码功能:计算一段字符串中有多少个符合要求的字串。
-
优点一:巧用>>和<<实现了对数据的灵活处理。
-
优点二:巧用hash数组以下标的方式实现了对子串的重复判断与个数计算