zoukankan      html  css  js  c++  java
  • C博客作业05--指针

    0.展示PTA总分

    1.本章学习总结

    1.1学习内容总结

    指针变量的定义

    类型名: *指针变量名
    例如:
    int *p;//定义一个整型变量p,指向整型变量;
    

    指针和数组的赋值与初始化

    一般情况下,数组的地址不能修改,内容可以修改;而指针的内容可以修改,指针指向的内容也可以修改,但这之前要为指针初始化。
    如:
    int p[5];
    p=p+1; //错误
    p[0]=1; //正确
    
    int *p;
    p=p+1; //正确
    p[0]=1;//错误,指针没有初始化;
    //
    int i; 
    int *p=&i;
    p[0]=1;//正确
    对于字符指针还有比较特殊的情况。
    如:
    char * p="abc";
    p[0]='d';//错误
    

    指针做循环变量做法

    例如:对数组元素求和
    int a[100];
    int *p;
    int sum=0;
    p=a;
    for(p=a;p<=&a[99];p++)
    {
    sum+=*p;
    }
    在循环中,指针变量p的初值是数组a的基地址,P连续取值&a[0],&a[1],…&a[99]。
    

    字符串指针如何表示字符串

    • 对指向字符变量的指针变量应赋予该字符变量的地址。
    例如:
    char c, *p=&c;//表示p是一个指向字符变量c的指针变量。
    char *s="apple";//表示s是一个指向字符串的指针变量。把字符串的首地址赋予s。
    
    • 用字符串指针指向一个字符串。
      例如:
    #include <stdio.h>
    int main(){
    char *string = "I love China!";
    printf("%s
    ", string);
    
    return 0;
    }
    

    动态内存分配

    • (1)函数malloc()
    原型:void* malloc(unsigned size);
    
    1.在内存的动态存储区中分配一块长度为size字节的连续区域,参数size为需要内存空间的长度,若申请成功,则返回指向所分配内存空间的起始地址的指针;若申请不成功,则返回NULL.
    2.函数malloc不能初始化所分配的内存空间,而函数calloc能.如果由malloc()函数分配的内存空间原来没有被使用过,则其中的每一位可能都是0;反之, 如果3.这部分内存曾经被分配过,则其中可能遗留有各种各样的数据.
    调用函数malloc()时,应该利用sizeof计算储存块的大小,不能直接写数值,因为不同平台数据类型占用空间大小可能不同。
    
    • (2)函数calloc()
    1.原型:void* calloc(size_t n, size_t size);
    2.参数size为申请地址的单位元素长度,n为元素个数,即在内存中申请n*size字节大小的连续地址空间.
    3.函数calloc()在内存的动态储存区中分配n个连续空间,每一个储存空间的长度为size, 并将所分配的内存空间中的每一位都初始化为零,如果是字符类型或整数类型的元素分配内存,那么这些元素将保证会被初始化为0;如果是为指针类型的元素分配内存,那么这些元素通常会被初始化为空指针;如果是实型数据分配内存,则这些元素会被初始化为浮点型的零.
    
    • (3)函数free()
    1.原型:void free(void *ptr);
    2.释放之后由动态储存分配函数申请的整块内存空间,ptr为指向要释放空间的首地址。free之后,申请内存的那个指针就会变成野指针,为避免出现野指针错误, 尽量在操作之后将指针置为NULL
    3.注意:申请和释放是一起的,所以程序是不能进行多次free同一个指针,否则程序会出错。释放之后不可以再通过该指针去访问已经释放的块,否则可能引起灾难性的错误
    

    指针数组及其应用

    • 非常容易混淆的两个概念:“指针数组”与“数组指针”
      指针数组:表示的是一个数组,数组中每一个变量都是指针型变量;
      数组指针:表示的是一个指针类型的变量,这个指针变量指向的是一个数组。

    • 数组指针
      定义int (*)data[10] = NULL;//定义了一个指向长度为10的int数组(int [10])的指针.

    • 指针数组:
      定义 int *p[n];
      []优先级高,先与p结合成为一个数组,数组名为p,该p数组中有n个元素,分别为p[0]、p[1]、……、p[n-1],每个元素均为指向int类型的指针变量(即(int *) p[n]),即元素的值为地址。

    指针数组应用:
    例:查找奥运五环色的位置,用指针数组实现
    #include<stdio.h>
    #include<string.h>
    int main()
    {
    int i;
    char *color[5]={"red","blue","green","black","yellow"};
    char str[20];
    scanf("%s",str);
    for(i=0;i<5;i++)
        if(strcmp(str,color[i])==0)
            break;
    if(i<5)
    printf("position:%d
    ",i+1);
     else
    printf("Not Found
    ");
    return 0;
    }
    

    二级指针、行指针

    • 二级指针
    定义:类型名 **变量名;
    例如:
    int a=10;
    int *p=&a;
    int **pp=&p;
    一级指针p指向整型变量a,二级指针pp指向一级指针p。由于p指向a,所以p和&a的值一样,a和*p代表同一个单元;由于pp指向p,所以pp和&p的值一样,pp和**p代表同一个单元
    
    • 行指针
    定义:int (*p)[3];
    *(p+i);//即a[i],第i行数组名,指向第i行0列的int型元素
    *(p+i)+j;//指向第i行j列的int型元素
    *(*(p+i)+j);//取出第i行j列的内容
    

    函数返回值为指针

    • 使用指针作为函数参数返回多个值的示例

      -运行结果

    1.2本章学习体会

    • 本章学习了指针,包括数组指针,指针数组,字符指针,一级、二级指针等重要内容,内容很多,相对来说也比较难,知识点抽象不易理解,做题无从下手。但是指针是学习C语言最重要的部分,务必要掌握,不能急躁,先理解它的概念,之后熟悉它的格式以及使用方法,多打代码练习。
    • 代码量有1000以上。

    2.PTA实验作业

    2.1题目7-2 藏尾诗

    2.1.1伪代码

    for i=0 to N
    输入字符串
    动态分配:p[i]=(char*)malloc(sizeof(str)+1)
    将输入的字符串复制到p[i]
    end for
    for i=0 to N
    求字符数组p[i]的长度
    输出最后一个字组成的字符串
    end for
    

    2.1.2代码截图

    2.1.3总结本题知识点

    动态分配:p[i]=(char*)malloc(sizeof(str)+1)
    将输入的字符串复制到p[i]:strcpy(p[i],str)
    求字符数组p[i]的长度:len=strlen(p[i])+1
    输出最后一个字组成的字符串:printf("%s",p[i]+len-2)
    

    2.1.4PTA提交列表及说明

    答案错误:一开始用fgets输入字符串,后来改为用fets输入,还是答案错误。
    答案错误:输出字符串的时候没有减去2。
    格式错误:刚开始用puts循环输出
    答案错误:改为用printf循环输出,写成了%c答案错误,再改为%s
    格式错误:在printf()里面加上了
    
    

    2.2题目6-10 填充矩阵

    2.2.1伪代码

    for i=0 to n
    for j=0 to n
    if(是副对角线上的元素)
    *(p[i]+j=1;
    end if
    if(是副对角线下方的元素)
    *(p[i]+j=2;
    end if
    if(是副对角线上方的元素)
    *(p[i]+j=3;
    end if
    end for 
    end for
    

    2.2.2代码截图


    2.2.3总结本题知识点

    副对角线上的元素:(i+j)==n-1
    副对角线下方的元素:(i+j)>n-1
    副对角线上方的元素:(i+j)<n-1
    取出第i行j列的内容:*(p[i]+j)
    

    2.2.4PTA提交列表及说明

    运行超时:不知道哪里错了,试试在每个if语句后面加个break,还是一样的结果。
    运行超时:一开始写的是*(*(p+i)+j),后来发现可以改成*(p[i]+j)。
    运行超时:找了很久发现if语句里面i+j没有加上括号,改成if((i+j)==n-1)
    答案错误:副对角线上方下方的元素是2还是3搞混了
    答案错误:写成了(i+j)==n,运行发现1都不在副对角线上,就改成(i+j)==n-1
    

    2.3题目6-6 查找子串

    2.3.1伪代码

    i=0,j=1;
    while(s[i])
    if(在字符串中找到子串的第一个字符)
    while(s[i+j]==t[j]&&t[j]!='')
    j++;
    end while
    if(t[j]=='')
    返回返回子串t在s中的首地址
    end if
    end if
    i++;
    end while
    

    2.3.2代码截图


    2.3.3总结本题知识点

    如果在字符串中找到子串的第一个字符,则开始从当前位置扫描子串
    if(s[i]==t[0]
    {
    while(s[i+j]==t[j]&&t[j]!='')
    j++;
    }
    返回子串t在s中的首地址:return s+i;
    

    2.3.4PTA提交列表及说明

    部分正确:搞不清楚j是从0开始还是从1开始。
    部分正确:错误写成当t[j]不等于0时返回子串t在s中的首地址。
    部分正确:不知道t在s中的首地址怎么表示。
    
    

    3.阅读代码





    • 代码功能:计算比赛中问题的最大期望值,并能实现找出字典上最小的序列,使预期数目的解决问题最大。
    • 代码优点:
      使用using namespace std调用命名空间std内定义的所有标识符,这样可以在不同命名空间里,起同样的变量名,防止变量名用尽或者冲突。
      调用多个头文件,赋予了调用某些函数的权限,便于进行类型检查,增加程序可读性。
      使用多次宏定义,实现了一些简单的函数功能,提升了程序编写的灵活性。
      使用typedef定义类型的别名,可以减少错误的发生,而且直观简洁。
  • 相关阅读:
    Jenkins持续集成
    爬豆瓣保存到sqlite3
    爬豆瓣保存到Excel
    sqlite3数据库的增删查改
    用pandas和matplotlib对用户消费行为分析
    TCP请求
    fastjson
    断言
    将结果写入文件
    加解密
  • 原文地址:https://www.cnblogs.com/4-Real/p/11951526.html
Copyright © 2011-2022 走看看