这个作业属于哪个班级 | C语言--网络2011/2012 |
---|---|
这个作业的地址 | C博客作业05--指针 |
这个作业的目标 | 学习指针相关内容 |
姓名 | 梁桢 |
0.展示PTA总分(0----2)
1.本章学习总结(3分)
1.1 指针定义、指针相关运算、指针做函数参数。
指针定义
- 使用指针可以对复杂数据进行处理,能对计算机的内存分配进行控制。
- 在函数调用中使用指针还可以返回多个值。
- 指针可以实现存储空间的动态分配。
- 指针所指的内容要初始化不然是野指针
定义 | 指针类型 |
---|---|
int *p | 指向p的整形指针 |
char *q | 指向q的字符指针 |
float *pp | 指向pp的浮点型指针 |
double *qq | 指向qq的双精度浮点数型指针 |
指针相关运算
定义 | 运算类型 |
---|---|
*(p)++ | 指针p所指内容+1 |
++*p | 指针指的的值+1 |
p++ | 指针移到下一位 |
指针做函数参数
void Printf( int *a , int *b)//传地址进去
int a = 5;
int *b;
b = &a;
Printf ( &a , b);
1.2字符指针
指向字符串、字符串相关函数及函数代码原型的理解、字符串相关函数用法
指向字符串
- 定义字符指针:char *p;
- 内容为字符串,同字符数组;
- 来输出字符指针的内容:使用printf("%s",p);
- p->str 首地址
字符串相关函数
函数名 | 函数格式 | 作用 | tip |
---|---|---|---|
#include<string.h> | 使用下列函数时候 | 必须包括 | |
strlen | strlen(a) | 计算字符串的长度 | 不包括字符串结束符' ' |
strcpy | strcpy(a,b) | 把b字符串内容赋给a字符串 | 注意第二个不要比越出第一个的长度 |
strcat | strcat(a,b) | 连接a,b2个字符串 | 第二个字符串的首字符在第一个的休止符上 |
strcmp | strcmp(a,b) | 比较两个字符串的大小 | a大1,b大-1,等大0 |
strstr | strstr(a,b) | 找第二个字符串在第一个字符串的出现的第一个地址 | 没找到为NULL |
malloc | a = (char)malloc(msizeof(char)) | 动态申请 | 用完要释放内存 |
1.3 指针做函数返回值
- 指针在函数内无返回值时应return NULL;
- 指针在不同定义类型的函数内的返回值应切合题意返回。
1.4动态内存分配
- 堆区和栈区
-
栈区(stack)
由编译器自动分配释放 ,存放函数的参数值,局部变量的值等,内存的分配是连续的,类似于平时我们所说的栈。
大小: 栈的大小是2M(也有的说是1M) -
堆区(heap)
一般由程序员分配释放, 若程序员不释放,程序结束时可能由操作系统回收.类似于链表,在内存中的分布不是连续的,它们是不同区域的内存块通过指针链接起来的.一旦某一节点从链中断开,我们要人为的把所断开的节点从内存中释放.
大小 :栈的大小是4G
申请堆区空间后要记得在使用完之后释放.
- 定义堆区
函数名 | 函数格式 | 作用 |
---|---|---|
calloc | calloc(n,s) | 分配n个大小为s的堆区 |
malloc | malloc(s) | 分配一个内存大小为s的堆区 |
- 举例多个字符串做动态内存要如何分配
#include<stdio.h>
#include<string.h>
int main()
{
char* s1;
char* s2;
s1 = (char*)malloc(8000000 * sizeof(char));//申请8000000个char单位的空间;
s2 = (char*)malloc(46000000 * sizeof(char));//申请46000000个char单位的空间;
free(s1);
free(s2);
return 0;
}
1.5 指针数组及其应用
二维字符数组与字符指针数组的区别
- 二维数组:一旦定义,那么每个字符数组的字符串最大长度和首地址都不能改变
- 字符指针数组:比二维字符数组更加灵活,其指向的每个字符串的首地址可以改变,字符串最大长度也可以改变。
1.6 二级指针
- 二级指针就是指向指针的指针,用于获取一级指针的地址
1.7 行指针、列指针
- 定义格式
行指针 :int (*p)[5];
格式 | 用法 |
---|---|
p+0或&p[0] | 指向第1个行的地址 |
p+1或&p[1] | 指向第2个行的地址 |
p+n-1或&p[n - 1] | 指向第n-1个行的地址 |
2.PTA实验作业
2.1 删除字符串中的子串
2.1.1 伪代码
char big[81];
char son[81];//定义主串和子串
char* p;//记录找到的子串的首地址
gets(big);
gets(son);//输入主串和子串
len = strlen(son);//记录子串长度
while (主串中找得到子串) {
归零*p;
strcat(big, p + len);//链接主串和主串+子串长度之后的字符串
}
输出重整后的主串
2.1.2 代码截图
同学的:
ta的代码比较繁琐对于判断子串的有无的代码较多。
俺的:
我的代码较为简洁,用strstr代替了较多繁琐代码。
2.2 合并2个有序数组
2.2.1 伪代码
void merge(int* a, int m, int* b, int n)
{
int sum = m + n;计录a最后的长度
int* c;
c = (int*)malloc((m + n) * sizeof(int));//定义新指针
if (m == 0) //把b数组给a,结束
if (n == 0) //直接结束
for (; k < sum; k++)//输入到c直到最后
{
if (j >= n)//如果数组b到结束
else if (i >= m)//如果数组a到结束
else if (a[i] < b[j])//正常判断输入a还是b到c中
}
把c的内存释放
2.2.2 代码截图
2.2.3 找一份同学代码
我的代码用了较多的分支进行分类讨论判断时和最后的比较,显得比较繁琐。
ta的代码写得较为简洁,但运行速度较慢。
2.3说反话-加强版
2.3.1 伪代码
{
定义一个输出结果数组
在堆中申请内存p = (char*)malloc(5000001 * sizeof(char*));
计算出字符串的总长度
for (小于总长度后退出)
{
if ()//判断是否为空格
{
把读输入到结果数组
计数长度
}
else//退出
{
长度归零
}
if (p[i] != ' ' && (p[i + 1] == ' ' || p[i + 1] == ' '))//判断是否最后一位
{
result[j][k] = 0;//输入休止符
j++;
}
}
}
输出第一个单词
}
2.3.2 代码截图
2.3.3超星视频做法区别
- 我的代码是从前到后逐个判断判断到最后,扫描结束后逐个输出字符串。
- 超新星:指针定位在字符串最后一个字符,从后往前逐个扫描到第一个空格,扫描结束后则输出指定长度字符串。