关于字符串和动态分配内存的学习

一、视频学习

1、观看视频:1.2.2动态内存分配、1.3.1单字符输入输出、1.3.2字符串数组、1.4字符串函数

2、手写笔记

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 3、代码列表

 

 

4、遇到的问题

(1)问题:观看视频1.3.1中不理解为什么单字符输入时要通过Ctrl+Z(Windows)或Ctrl+D(Unix)才能结束输入。

         结果:查阅相关信息得知视频中所说的shell在遇到文件结束符(EOF)前仍会等待用户输入数据,正如视频中翁恺老师在输入一堆字符敲下回车后程序仍未结束。而Ctrl+Z与Ctrl+D相当于文件结束符(EOF)当shell接收到文件结束符时才结束程序。

(2)问题:在观看视频1.3.2程序参数时对于argv[1]、argv[2]等的输出方式存在疑惑,不知怎么输出。

         代码:

                  #include<stdio.h>
                  int main(int argc,char const *argv[]){
                  int i;
                  for(i=0;i<argc;i++){
                  printf("%d:%s\n",i,argv[i]);
                  }
                  return 0;
                  }

         结果:错误尝试: int main(int argc,char const *argv[]={,1354641,asfgasdg})、int main(int argc,char const *argv[]){char const*argv[]={51351,sdgds}}

                   询问老师后得知,argv[x](x=!0)从DEVC++运行一栏的参数选项中添加

                  如图:

                 

 二、PTA中遇到的问题

1、问题: PTA2-1以下不正确的赋值或赋初值的方式是( )。 

                 A、char str[]="string";
                B、char str[7]={'s', 't', 'r', 'i', 'n', 'g'};
                C、char str[10];str="string";
                D、char str[7]={'s', 't', 'r', 'i', 'n', 'g', ’\0’};

     知识点:字符串定义方式①char s1[]={'a','b','c','\0'};(字符串数组)

                                    ②char s2[]="abc";(字符串数组)

                                    ③char *sp="abc";(字符串指针)

    答案:C,C选项直接对str[1]进行了赋值,然而指针常量不能直接赋值。

2、问题:字符串数组与字符串指针区别

      区别:①. ”读“ ”写“ 能力

                      char *a = “abcd”; 此时"abcd"存放在常量区。通过指针只可以访问字符串常量,而不可以改变它。
                     而char a[20] = “abcd”; 此时 "abcd"存放在栈。可以通过指针去访问和修改数组内容。
                ②. 赋值时刻
                     char *a = “abcd”; 是在编译时就确定了(因为为常量)。
                    而char a[20] = “abcd”; 在运行时确定
              ③. 存取效率
                   char *a = “abcd”; 存于静态存储区。在栈上的数组比指针所指向字符串快,因此慢。
                   而char a[20] = “abcd”; 存于栈上,更快。

3、问题:5-1消除空格判断是否回文

     代码:

               #include <stdio.h>
               #include <string.h>
               int main(void) {
               char s[80], ch, *p, *q;
               int i, j, n;
               gets(s);
               p =   ;
              while ( *p == ' ')
                           ;
              n = strlen(s);
              q =    ;
              while ( *q == ' ')
                           ;
              while (      && *p ==*q) {
              p++;
                            ;
               }
               if ( p<q )
               printf("NO\n");
               else
               printf("YES\n");
               return 0;
               }

结论:消除前空格易想到从数组首位数据开始逐一往后判断是否为'  ',而消除后空格易想到从数组末位数据开始逐一往前判断是否为'   '。根据代码信息while ( *p == ' ')______;与while ( *q == ' ')_____;观察到这两个语句中的*p与*q分别与'    '进行比较,故作用极有可能为消除前后空格。 前者由前置语句p=__;组成易得p=s;while ( *p == ' ')p++;。后者有前置语句n=strlen(s);q=__;可得q=s+n-1;while ( *q == ' ')q--;题目要求在消除空格后判断回文,易得回文形式为s[0]==s[n-1];s[1]==s[n-2]······s[(n-1)/2-1/2]==s[(n-1)/2+1/2](n-1为奇数)或s[(n-1)/2]==s[(n-1)/2](n-1为偶数)。由先前的代码信息基本可以确定消除空格后p将指向数组s的首位数据(非' '),而q将指向数组s的末尾数据(非' ')则回文判断可简化为判断*p是否与*q相等再将p和q移向下一位当到达p==(n-1)/2-1/2和q==(n-1)/2+1/2或者p==(n-1)/2-1与q==(n-1)/2+1时进行最后一次判断再移向下一位,通过判断q与p最终指向的位置是否相等或p>q至此得出数组s是否为回文既if ( p<q )printf("NO\n");else printf("YES\n");。易得题中控制条件的语句为while(____&&*p==*q)已有*p与*q是否相等的判读指向再判断p是否超过(n-1)/2-1/2与q是否超过(n-1)/2+1/2或者p是否超过(n-1)/2-1与q是否超过(n-1)/2+1,既p是否小于q。故此空填p<q;而后续由p++;可得在while语句中要实现的功能是两个指针由两边不断地往中间移位,故下一句填q++;。

答案:(1)s(2)p++(3)s+n-1(4)q--(5)p<q(6)q--

4、问题:PTA2-2假设scanf语句执行时输入ABCDE<回车>,能使puts(s)语句正确输出ABCDE字符串的程序段是__。 

                           A、char s[5]={"ABCDE"}; puts(s);
                           B、char s[5]={'A', 'B', 'C', 'D', 'E'}; puts(s);
                           C、char *s; scanf("%s", s); puts(s);
                           D、char *s; s="ABCDE"; puts(s);

      答案:D

      结论:puts(s)在遇到 '\0'前会一直输出下去直到遇到不可识别的数据故A、B输出不正确或偶然输出正确。而C选项没有提前给指针s分配足够的空间故错误。

posted @ 2020-03-15 14:14  板蓝根拌饭  阅读(991)  评论(2编辑  收藏  举报