C博客作业05--指针

| 这个作业属于哪个班级 | C语言--网络2011/2012 |
| ---- | ---- | ---- |
| 这个作业的地址 | C博客作业05--指针 |
| 这个作业的目标 | 学习指针相关内容 |
| 姓名 | 吴俊豪 |

0. 展示PTA总分

1. 本章学习总结

1.1 指针定义、指针相关运算、指针做函数参数

int fun(int *a);
int *p;//指针定义
int n;
int num[50];
p = num;
num[0]=1;
*(p)++;//指针所指内容自增
p++;//指针移动到下一位
n=fun(p);//向函数传入指针的地址

常用的string指针库函数

函数名 函数格式 作用 备注
strcpy strcpy(a,b) 把b字符串内容赋给a字符串 可以使用strncpy能自定义赋值的位数
strcmp strcmp(a,b) 将a串与b串比较 1.a大值为1,b大值为-1,相等值为0. 2.可以使用strncmp自定义比较位数
strcat strcat(a,b) 把b串从头接到a串末尾 可以使用strncat自定义追加位数
strstr strstr(a,b) 在a串中找到b串首次出现的地址 不会包含结束符
更多string库函数请移步C 标准库 - <string.h>

1.2 字符指针

  1. 定义字符指针:char *p;
  2. 字符指针的内容为字符串,字符数组是一种特殊的字符指针.
  3. 使用printf("%s",p);来输出字符指针的内容.
  4. 使用指针指向字符串,例:p=(str+i);

1.3 指针做函数返回值

  1. 指针在函数内无返回值时应return NULL;
  2. 指针在不同定义类型的函数内的返回值应切合题意返回,诸如int,double,int *,char *等等

1.4 动态内存分配

  1. 堆区与栈区
    (1)栈区:存放函数的参数值、局部变量等,由编译器自动分配和释放,效率很高,但是分配的内存量有限.
    (2)堆区:就是通过new、malloc、realloc分配的内存块,编译器不会负责它们的释放工作,需要用程序区释放。分配方式类似于数据结构中的链表。“内存泄漏”通常说的就是堆区.

  2. 使用函数:

函数名 函数格式 作用 备注
calloc calloc(n,s) 分配n个大小为s的堆区 返回值类型为void,通常需要进行强转
malloc malloc(s) 分配一个内存大小为s的堆区 返回值类型为void,通常需要进行强转

注:申请堆区空间后要记得在使用完之后释放.

  1. 举例多个字符串做动态内存要如何分配
#include<stdio.h>
#include<string.h>//函数malloc的库;
int main()
{
char* a;
char* b;
a = (char*)malloc(m*sizeof(char));//给a申请m个char单位的空间;
b = (char*)malloc(n*sizeof(char));//给b申请n个char单位的空间;
Function(a,b);//使用a,b字符串;
free(a);
free(b);//使用完手动释放内存;
return 0;
}

1.5 指针数组及其应用

二维字符数组:一旦定义,那么每个字符串的最大长度、首地址都不能改变了.
字符指针数组:由于它仅用来存放指针,所以它指向的每个字符串的首地址可以改变,字符串最大长度也可以改变,相较二维字符数组更加灵活.

1.6 二级指针

二级指针就是指向指针的指针.

1.7 行指针、列指针

(1)行指针:通常写作p+i,取值时为(p+i);
(2)列指针:通常写作p[0]+i,取值时为
(p[0]+i);

2.PTA实验作业

2.1 藏尾诗

2.1.1 伪代码

ch[20][20]//用于存放诗句
d[20]//用于存放尾巴
i<-0
j<-0
while i<4
      do scanf ch[i]
      d[j] <- *(ch[i] + strlen(ch[i]) - 2)
      d[j+1] <- *(ch[i] + strlen(ch[i]) - 1)//一个汉字占两个字节
      j+=2
      i++
end while
d[j]<-0//添加结束符
printf d

2.1.2 代码截图

2.1.3 代码比较

同学的代码:

#include <stdio.h>  
#include <stdlib.h>  
#include "math.h"  
#include "string.h"  
  
int main()  
{  
   char *p[4],str[20];  
   int i;  
   for(i=0;i<=3;i++){  
       fgets(str,19,stdin);
       p[i]=(char *)malloc(sizeof(str)+1);  
       strcpy(p[i],str);  
  
   }  
  
   int n;  
  
   for(i=0;i<=3;i++){  
      n=strlen(p[i])-1;  
      printf("%s",p[i]+n-2);  
   }  
  free(p);
   return 0;  
}  

两份代码最大的区别在于同学使用了动态内存申请,我则选用二维字符数组,相较之下同学的代码可以适应更加极端的情况(诗句数量特别多时).

2.2 合并2个有序数组

裁判测试程序:

#include <stdio.h>
#include <stdlib.h>

void printArray(int* arr, int arr_size);  /* 打印数组,细节不表 */
void merge(int* a, int m, int* b, int n); /* 合并a和b到a */

int main(int argc, char const *argv[])
{
    int m, n, i;
    int *a, *b;

    scanf("%d %d", &m, &n);
    a = (int*)malloc((m + n) * sizeof(int));
    for (i = 0; i < m; i++) {
        scanf("%d", &a[i]);
    }

    b = (int*)malloc(n * sizeof(int));
    for (i = 0; i < n; i++) {
        scanf("%d", &b[i]);
    }
    merge(a, m, b, n);
    printArray(a, m + n);

    free(a); free(b);
    return 0;
}

2.2.1 伪代码

void merge(int* a, int m, int* b, int n)
static hash[100001]
i,j
for i=0 to m
    hash[a[i]]++
end for    
for i=0 to n
    hash[a[i]]++
end for  
for i=0 to 100001
    for j=0 to hash[i]
        *a = i;
        a++
    end for
end for

2.2.2 代码截图

2.2.3 代码比较

同学代码:

void merge(int* a, int m, int* b, int n, int* c)
{
    int i=0,j=0,k=0;
    while(i<m&&j<n)
    {
        if(*a>=*b)
        {
            c[k]=*b;
            b++;j++;k++;
        }
        else
        {
            c[k]=*a;
            a++;i++;k++;
        }
    }
    if(i<m)
    {
        while(k<=m+n-1)
        {
            c[k]=*a;
            a++;
            k++;
        }
    }
    if(j<n)
    {
        while(k<=n+m-1)
        {
            c[k]=*b;
            b++;
            k++;
        }
    }
    for(i=0;i<m+n;i++)
    {
         a[i]=c[i];
    }
}

两份代码几乎就是两个不同的思路,同学是先将a,b数组按次序存入c数组,然后再把c数组的内容赋给a数组;我则是使用一个新数组将a,b中出现的数字在数组hash内计次,最后把hash内的数组下标赋值给a数组.

2.3 说反话-加强版

2.3.1 伪代码

ch[500100]
flag<-0
fgets ch
int *endp -> ch
while *endp != '\0' && *endp != '\n'
      do endp++
end while/*把指针移动到最后*/
while p != ch /*循环至字符串开头*/
      do if *p != '.'
               then len++
               用flag控制空格并输出p
               len<-0
          end if
      p--
end while
if *ch!=' '
    then 用flag控制空格并输出p
return 0

2.3.2 代码截图


2.3.3 与超星视频的区别

我的代码是基于超星视频的思路编写的,所以除了一些小细节外几乎没有太大的区别.

posted @ 2020-12-27 11:18  Qurare  阅读(142)  评论(0编辑  收藏  举报