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定义类型的别名,可以减少错误的发生,而且直观简洁。
  • 相关阅读:
    184. Department Highest Salary【leetcode】sql,join on
    181. Employees Earning More Than Their Managers【leetcode】,sql,inner join ,where
    178. Rank Scores【leetcode】,sql
    177. Nth Highest Salary【leetcode】,第n高数值,sql,limit,offset
    176. Second Highest Salary【取表中第二高的值】,sql,limit,offset
    118. Pascal's Triangle【LeetCode】,java,算法,杨辉三角
    204. Count Primes【leetcode】java,算法,质数
    202. Happy Number【leetcode】java,hashSet,算法
    41. First Missing Positive【leetcode】寻找第一个丢失的整数,java,算法
    删除
  • 原文地址:https://www.cnblogs.com/4-Real/p/11951526.html
Copyright © 2011-2022 走看看