《C和指针》学习笔记(1)

最近C语言已经学完,布置的大作业:学生管理系统5个版本也完成了。但是又买了一本《C和指针》,主要是感觉自己的指针还是没有完全熟悉。所以还是要好好研究一下。闲话不多说,直接第一章。一看是快速入门,以为很简单,但那个程序就把我卡了半天才看懂,按照作者说的的确运用了C语言中的大部分技巧。

程序1.1:首先读取一串列标号,这些列标号成对出现,便是输入行的列范围。这串列标号以一个负值结尾,作为结束标志。剩余的输入行被程序读入并打印,然后输入行中被选中范围的字符串被提取出来打印。

书中代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CLOS 20         /*所能处理的最大列号*/
#define MAX_INPUT 1000       /*每个数入行的最大长度*/
int read_column_numbers(int columns[],int max);
void rearrange(char *output,char const*input,int n_columns,int const columns[MAX_CLOS]);
int main(void)
{
   int n_columns;           /*进行处理的列标号*/
   int columns[MAX_CLOS];   /*需要处理的列数*/
   char input[MAX_INPUT];    /*需要容纳的输入的数组*/
   char output[MAX_INPUT];   /*容纳输出行的数组*/

   n_columns=read_column_numbers(columns,MAX_CLOS);
   while(gets(input)!=NULL) /*如果读入不存在输入行则程序结束*/
   {
       printf("Original input :%s\n",input);
       rearrange(output,input,n_columns,columns);
       printf("Rearranged line :%s\n",output);
   }
   return EXIT_SUCCESS;
}

/*读取需要处理的列标号,如果超出规定范围不予理会*/
int read_column_numbers(int columns[],int max)
{
    int num=0;
    int ch;
    while(num<max&&scanf("%d",&columns[num])==1&&columns[num]>0)
    {
        /*这个循环条件保证了读取的行号不会超过最大值,而且利用&&的短路特性,
          也不会即使超过最大行号也不会被scanf读入,同时scanf保证了读入整型数据,
          同时后面的条件输入的为正数*/
          num+=1;
    }
    /*判断是否读入的数据是成对的*/
    if(num%2)
    {
        puts("Last column number is not paired.");
        exit(EXIT_FAILURE);
    }
    while((ch=getchar())!=EOF&&ch!=‘\n‘);  /*用来处理包含最后那个负值的所有字符*/
    return num;
}
/*处理输入行*/
void rearrange(char *output,char const*input,int n_columns,int const columns[MAX_CLOS])
{
    int col;                                            /*columns数组的下标*/
    int output_col;                                     /*输出行的列计数器*/
    int len;                                            /*输入行的长度*/
    int nchars;                                         /*成对处理的列之间的长度*/
    len=strlen(input);
    output_col=0;
    for(col=0;col<n_columns;col+=2)
    {
        if(columns[col]>=len||output_col==MAX_INPUT-1)  /*如果输入行的标号小于需要处理的列标号或者
                                                          输出数组已满结束任务*/
            break;
        nchars=columns[col+1]-columns[col]+1;
        if(output_col+nchars>MAX_INPUT-1);
            nchars=MAX_INPUT-output_col-1;              /*如果输出行数据空间不够则只处理到能容纳到的数据*/
        strncpy(output+output_col,input+columns[col],nchars);
        output_col+=nchars;
    }
    output[output_col]=‘\0‘;
}

一点点思考:不得不说,Kenneth这种大师思维的确很完善,要是我写的确很多地方都想不到(我怎么敢和大师比2333!),比如while(ch=getchar())那个语句,一开始我百思不得其解,后来才明白为的是清除负值之后的字符(包括负值本身)因为这些字符虽然没有被读走,同时也仍然在stdin中存在。所以在主函数调用gets这个函数进行读取的时候这些未被读走的字符就会被解释为第一行数据进而使我们得不到自己想要的结果。 而他对于可能造成数组越界访问的情况也进行了处理。想想自己在写的时候从来没有在乎过这些,都是越界了才会debug找出来。另外一个细节就是他传入rearrange这个函数的input数组,加了前缀const,防止函数内可能造成的改动。这点也是我需要学习的。

不过我也对于他的主函数设置的while条件有一些异议,gets函数在读到文件尾(EOF)才会得到NULL,这种的确适合我们打开一个文件进行读取的操作,因为这个文件的末尾一定会有EOF。但是如果我们在键盘输入的时候,我们只有CtrlZ才可以得到EOF,这点总让我感觉很不爽,其实主要是我懒不想摁CtrlZ,另外是我在书上并不是很理解它的输入样例(大家可以去看一下),里面没有CtrlZ,所以,我并不是很懂作者的意思。但貌似没有其他更好的方法了。就暂且认为是需要输入CtrlZ。在这个问题上纠结这么久,我也是醉了。

这个程序的确很经典,包含的东西多但不难,其实大家可以按照示例试一下输出,然后就会得到很好玩的结果了。感觉自己学了一学期C,还是什么都不会,自己打的时候打不下去,然后看了书的程序也是看了半天。。。可能是因为最近在看Java导致的吧。不能一天放松啊。。。

时间: 2024-10-29 19:07:05

《C和指针》学习笔记(1)的相关文章

Java性能调优笔记

Java性能调优笔记 调优步骤:衡量系统现状.设定调优目标.寻找性能瓶颈.性能调优.衡量是否到达目标(如果未到达目标,需重新寻找性能瓶颈).性能调优结束. 寻找性能瓶颈 性能瓶颈的表象:资源消耗过多.外部处理系统的性能不足.资源消耗不多但程序的响应速度却仍达不到要求. 资源消耗:CPU.文件IO.网络IO.内存. 外部处理系统的性能不足:所调用的其他系统提供的功能或数据库操作的响应速度不够. 资源消耗不多但程序的响应速度却仍达不到要求:程序代码运行效率不够高.未充分使用资源.程序结构不合理. C

JAVA性能调优-在循环条件中不要使用表达式

1.JAVA性能调优-在循环条件中不要使用表达式 我们在学习JAVA性能调优的时候,经常能看到这一的一段话:在不做编译优化的情况下,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快. import java.util.vector; class cel { void method(vector vector) { for (int i= 0; i < vector.size (); i++)  //violation ; //... } } 更正:

java 性能调优工具

1.jstack 用法jstack [option] pid -l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况 -m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法) 找出进程内最耗费CPU的线程,可以使用ps -Lfp pid或者ps -mp pid -o THREAD, tid, time或者top -Hp pid printf "%x\n" pid 得到pid的

java 性能调优和GC

JAVA 性能调优和GC http://blog.csdn.net/gzh0222/article/details/7663181 JAVA GC调优手记 http://blog.csdn.net/firecoder/article/details/7225654 JAVA GC 日志详解 http://blog.csdn.net/alivetime/article/details/6895537 JAVA 内存参数设置 http://heipark.iteye.com/blog/1356113

Java性能调优_深入Java程序性能调优(并行开发、JVM调优)

深入Java程序性能调优(阿姆达尔定律.缓存组件.并行开发.线程池.JVM调优)课程讲师:special课程分类:Java核心适合人群:初级课时数量:33课时更新程度:完成用到技术:阿姆达尔定律.缓存组件.并行开发.线程池.JVM调优涉及项目:模式在实际开发中运用深入Java程序性能调优下载: http://pan.baidu.com/s/1ntn0ZTB 密码: ijluJava性能调优:国内关于Java性能调优的课程非常少,如此全面深入介绍Java性能调优,北风算是独家,Special讲师,

JAVA性能调优- try/catch块和循环

1.JAVA性能调优-将try/catch块移出循环 据说把try/catch块放入循环体内,会极大的影响性能.因为使用了try/catch模块的使用,会让JAVA虚拟机做很多额外的工作.就好比对每个人说,"嗨,哥们,路上可能有蛇.于是听到的人只好手拿木棍,小心翼翼的往前走". 把try/catch块放到循环外面,就好比对一大群人说,"嗨,兄弟们,路上可能有蛇.于是听到的人安排部分人员拿木棍往前走,其他人基本不受影响" 这个理论蛮不错的,测试下对性能的实际影响 2.

推荐书籍:《Java性能调优指南》

本书作者是Java性能和Java HotSpot 虚拟机领域的佼佼者,帮助你利用现代软工实践提高性实战生涯中总结能,避免常见错误,从技巧和窍门. 利用G1克服并行.串行和CMS垃圾收集器的局限性了解G1  GC收集的各个阶段,包括年轻代和老年代在G1的引擎下微调您的应用程序确定潜在优化方案,解释实验结果,并付诸行动探索的HotSpot虚拟机内部使用热点VM服务代理分析.分流,并解决不同的热点 <Java性能调优指南>主要展示了如何在当今先进的多核硬件和复杂的操作系统环境下,系统且主动地提高Ja

java性能调优——技客时间

一.java性能调优的标准 cpu:有的应用需要大量计算,他们会长时间.不间断地占用 CPU 资源,导致其他资源无法争夺到 CPU 而响应缓慢,从而带来系统性能问题.例如,代码递归导致的无限循环,正则表达式引起的回溯,JVM 频繁的 FULL GC,以及多线程编程造成的大量上下文切换等,这些都有可能导致 CPU 资源繁忙. 内存:Java 程序一般通过 JVM 对内存进行分配管理,主要是用 JVM 中的堆内存来存储 Java 创建的对象.系统堆内存的读写速度非常快,所以基本不存在读写性能瓶颈.但

《Java性能调优》学习笔记(1)

性能的参考指标 执行时间 -- 从代码开始运行到结束的时间 CPU时间 -- 函数或者线程占用CPU的时间 内存分配 -- 程序在运行时占用内存的情况 磁盘吞吐量 -- 描述IO的使用情况 网络吞吐量 -- 描述网络的使用情况 响应时间 -- 系统对某用户行为或者时间做出的响应时间 性能的瓶颈资源可能有: 磁盘IO 网络操作 CPU 异常 -- 对Java应用来说,异常的补货和处理是非常消耗资源的,如果程序高频率的对异常处理会对整体性能有影响 数据库 锁竞争 -- 增加上下文切换的开销 内存 性

成为Java GC专家(5)—Java性能调优原则

这是"成为Java GC专家"系列的第五篇文章.在第一篇深入浅出Java垃圾回收机制中,我们已经学习了不同的GC算法流程.GC的工作原理.新生代(Young Generation)和老年代(Old Generation)的概念.你应该了解了JDK7中5种GC类型以及各种类型对应用程序的影响. 在第二篇如何监控Java的垃圾回收中,阐述了JVM是怎样实际执行垃圾回收的,我们怎样去监控GC以及哪些工具能让这个过程更高效. 第三篇如何如何优化Java垃圾回收机制中展示了一些基于真实案例的最佳