第六篇博客
| 这个作业属于哪个班级 |
| ---- | ---- | ---- |
| 这个作业的地址 |
| 这个作业的目标 | 学习数组相关内容 |
| 姓名 | 卢伟杰 |
0.展示PTA总分
1.本章学习总结
1.1 指针定义、指针相关运算、指针做函数参数
-
地址和指针
直接访问 :通过变量名访问
int x = 20,y = 1,z = 155; printf(“%d”, x);
间接访问 :通过地址访问
int *p; printf(“%d”, *p);
-
变量名的定义
指针变量的定义 :类型名 *指针变量名
-
指针变量所指向的变量的类型
int *p; 整形指针 float *p 浮点型指针 char *p 字符型指针
-
-
指针的基本运算
指针的值是某个变量的值
如 : int *p,a = 3; // * 表示取内容
p = &a; // & 表示取地址
把a的地址赋给p;
*p :是直接对内存单元操作,改变变量的数据;
(*p)++ 等于 将 p 所指向的变量值加一;
(*p++) 等于 先取*p,然后p加一,p不再指向原地址;
相同类型的指针才能相互赋值。
- 指针的算术运算和比较运算
double *p,*q;
a. q - p :两个相同类型指针相减,为相隔的单位;
b. p + 1/p - 1 :下一个存储单元/上一个存储单元;
c. p < q :两个相同类型指针可以比较大小;
除此之外,其他操作都是非法的。
- 指针变量的初始化
指针变量先定义,赋值必须是地址。
如 : int a,*p; p = &a;
且在定义指针变量时,可以同时对它赋值。
不能用数值作为指针变量的初值,但可以将指针变量初始化为空指针。
方法 :p = 0; 或 p = NULL;
!:指针没有指向是危险的野指针,发生段错误!!
1.2 字符指针
-
字符指针中的const
const :定义的是变量,但又相当于常量;只读变量,不允许重新赋值。 -
字符串的处理函数
A. stdio.h
字符串的输入和输出:
输入字符串 :scanf()或 fgets();
输出字符串 :printf()或 puts();
B. string.h
* 字符串的复制 :
strcpy(str1,str2): 把字符串str2复制到str1中。
char *strcpy(char *str1,const char *str2)
源字符串要足够大,否则会溢出崩溃。
* 字符串的连接 :
strcat(str1,str2): 连接两个字符串str1和str2,并将结果放入str1中。
char *strcpy(char *str1,const char *str2)
源字符串要足够大,否则会溢出崩溃。
* 字符串的比较 :
strcmp(str1,str2): 比较字符串的内容大小。
格式 :if(strcmp (str1 > str2)) { }
* 字符串的长度 :
strlen(str):计算字符串的有效长度,但不包括'\0'。
例如 :strlen("hello")的值是5;
static char str[20] = "how are you?"
strlen(str)的值是12;包括空格与符号。
一般用法 :int len,str;
len = stelen(str);
* 字符串的相同位置 :
strpbrk(str1,str2): 检索字符串str1中第一个匹配字符串str2中字符的字符。
strchr(str1,'c') : 搜索字符串str中最后一次出现字符c的位置。
strstr(str1,"abcd"):查找字符串str1中第一次出现字符串abcd的位置。
1.3 指针做函数返回值
-
一般定义的格式 :数据类型 *函数名称
double *Fun(double x,double y); -
注意事项 :
1.该地址所指向的空间是否存在,野指针十分危险。
2.函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、
局部数组和形式参数,函数返回的指针请尽量不要指向这些数据。
1.4 动态内存分配
-
为什么要动态分配内存:
堆区申请的空间,想要多少申请多少。
数组要指定数组长度,造成空间浪费。
栈区的空间有限。
程序的灵活性更高、可以释放空间。
-
堆区和栈区的区别 :
(1)管理方式不同:栈直接由编译器管理,堆由程序员手动管理(产生和消除)。
(2)空间大小不同:栈占用的空间小,而堆占用的空间大。
(3)能否产生碎片不同:栈不会产生碎片,但是堆会产生碎片。
(4)生长方向不同:栈是向下压栈,堆是向上存放数据。
(5)分配方式不同:栈没有经过初始化的变量,只有动态分配方式。
堆经过初始化的变量,动态分配和静态分配都可以。(6)分配效率不同:栈效率比较高,堆空间效率比较低。
-
动态分配内存的相关函数 :
计数动态分配存储函数 callo()
#include <stdlib.h>
if ((p = (int*)callo(n,sizeof(int))) == NULL)
{
printf("not able to allocate money.\n");
exit(1);
}
计数动态分配存储函数 mallo()
#include <stdlib.h>
p = (int*)mallo(n*sizeof(int));
若申请成功,则返回一个指向所分配空间的起始地址的指针p,若失败则返回NULL;
返回类型 void(*),赋给指针要强制转换。
和free结合使用。
动态存储释放函数 free()
#include <stdlib.h>
free(p);
1.5 指针数组及其应用
-
二维字符数组一旦定义,那么每个字符串的最大长度、首地址都不能改变了。
-
字符指针数组是存放字符指针的数组。它指向的每个字符串的首地址可以改变,
字符串最大长度也可以改变。 -
相比而言,字符指针数组更灵活一些。
1.6 二级指针
-
指向指针的指针。
-
分为指向指针变量的指针、指向指针数组的指针。
1.7 行指针、列指针
- 行指针 :指向首地址,一整行
表示形式 | 含义 | 指针类型 |
---|---|---|
a | 指向第0行 | 行指针 |
a+1 | 指向第1行 | 行指针 |
a+2 | 指向第2行 | 行指针 |
- 列指针 :指向元素
表示形式 | 含义 | 指针类型 |
---|---|---|
a[0] | 第0行,第1个元素的地址 | 列指针 |
a[0]+1 | 第0行,第2个元素的地址 | 列指针 |
a[0]+2 | 第0行,第3个元素的地址 | 列指针 |
2.PTA实验作业
2.1 藏尾诗
2.1.1 伪代码
定义数组来存放最后一个字 str[20]
定义二维数组用来输入诗 poem[i][20]
定义每行诗的长度 int len
for i = 0 to 4
do len = strlen(poem[i]) //得到每行诗的长度
str[j++] = poem[i][len - 2] //得到尾字的第一个字符
str[j++] = poem[i][len - 1] //得到尾字的第二个字符
给尾字结束符 str[j] = '\0'
输出含所有尾字的数组str
2.1.2 代码截图
2.1.3 找一份同学代码
2.2 合并2个有序数组
2.2.1 伪代码
用strcat将a,b数组结合起来 strcat(a,b)
strlen得到数组的长度 len = strlen(a)
通过选择法排序对数组 a 进行升降排序
for i = 0 to len
if (strcmp) {strcpy()};
printf 数组a。
2.2.2 代码截图
2.2.3 找一份同学代码
2.3 说反话-加强版
2.3.1 伪代码
主要在于函数方面 :
void RecerseStr(char *beginPtr)
{
定义尾部指针 endPtr = beginPtr
while(*endPtr)endPtr++; //指针定位到字符串尾部
遍历指针 p = --Ptr
while(p != beginPtr)
{
若*p不是空格,则统计单词长度len。
若*p不是空格但是前一个字符是空格;
则找到单词,输出从p开始的len长度字符串,len=0
p--
}
输出第一个单词
}
2.3.2 代码截图
2.3.3 请说明和超星视频做法区别,各自优缺点
- 就是从超星视频上学习才会的。