Ryen的学习笔记

成长有多少新奇的美,就有多少撕裂的痛;离去有多么辽阔的自由,就有多么无边的孤寂。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

《算法竞赛入门经典》读书笔记一 之 编程基础(I/O)

Posted on 2010-01-12 17:02  Ryen_lee  阅读(500)  评论(0)    收藏  举报

第一章

  • 数值变量的分类及字面值,VS2008平台.
关键字 类型 位数(字节) 范围 字面值举例
int 整型 4 -2147483648 ~2147483647,约21亿 23
long 整型 4 同上 15
long long 整型 8 -2^63 ~ 2^63-1 234
short 整型 2 –32768 ~ 32767 N/A
unsigned 整型 4 0 ~ 2^32 - 1* 128u
float 浮点型 4 -2^128 ~ +2^128 2.5f, 1e-3F
double 浮点型 8 -2^1024 ~ +2^1024 3.2,  21e4

         (注: 字面值中的字母 u,e,f,l大小写均可,l一般大写,便于和1区分)

  • 闰年的判断

 

if( ((year%4==0)&&(year%100 != 0)) || (year%400==0) )
printf(
"yes");
else
printf(
"no");

 

  • printf输出的格式字符串

               “%3d”用空格补足3位,”%03d”用0补足3位 

第二章

  • 输入重定向

freopen("input.txt", "r", stdin);
freopen(
"output.txt", "w", stdout);

 

第三章

  • ++count 和 count++

         两者在表达式中看成一个整体,前者先加后取值,后者取值后再加,不过先后在很多情况下不好定义,所以一般在有歧义的地方不建议使用。

  • 回车换行符

           '\r'是回车符,将光标转到行首;‘\n'是换行符,将光标转到下一行

           windows: '\r''\n'

           Linux: '\n'

           Max: '\r'

  • 补码表示法

        使用补码表示法的原因是计算方便,大多数计算机系统中,整数都是用补码表示。

  • 输入缓冲区和scanf函数

        控制台的输入输出可以认为是基于stdin和stdout这两个流的操作,缓冲区可以认为是这个流的内存空间。

        这样可以当成文件来处理。可以参见这两篇文章 scanf() 与空格由scanf("%d",&ch);引出的输入缓冲区问题

           一般来说,C语言处理输入都是基于缓冲的,这就需要一个触发的操作,只有输入回车后,scanf函数才开始从缓冲区中读入,也即开始处理缓冲区。

       如果想通过读入EOF跳出scanf函数可以参见我的这篇帖子

代码
/*
scanf函数会过滤空格,回车,换行,TAB,在它后面的这些输入它不读取,仍然将其留在缓冲区中。
*/

int main()
{
int a = 0;
char c;
scanf(
"%d",&a);
scanf(
"%c", &c);
printf(
"%d %c", a, c);
return 0;
}
//输入: “abc”
//输出: “0 a”

//scanf("%d "), 中的空格会吃掉缓冲区后面的空白符

  • I/O相关:

char * gets ( char * str ) : 从缓冲区中读入字符放入str中,直至遇到‘\n’或EOF为止结束读取(会吃掉缓冲区的'\n'),但是‘\n’并不放入str中,而是在str尾部添加‘\0’. 
如果没有读到一个字符,返回NULL。

char * fgets ( char * str, int num, FILE * stream ) : 结束条件是 1. 已经读入 num-1个字符 或 2. 遇到‘\n’或 3. 遇到EOF。 如果读到‘\n'并不吃掉,而是加到str中。
最后也是自动加上'\0'。该函数如果当读到EOF时还没有读到一个字符('\n'也没有读到),就会返回NULL。

int scanf ( const char * format, ... ) : scanf("%d") 遇到空白符终止,但不吃掉空白符. 失败时返回EOF.

int getc ( FILE * stream ) : 注意需要 一个FILE 指针。该函数基本等同 fgetc(FILE * stream)

int getchar ( void ) : 不用参数,类似的有getch, getche 主要区别是显示器回显问题。
  • 数组的初始化

         可以参见这篇文章

代码
/*
初始化值的个数可少于数组元素个数.当初始化值的个数少于数组元素个数时,前面的按序初始化相应值, 后面的初始化为0(全局或静态数组)或为不确定值(局部数组).
*/

char cname[256]={0};

int v1[] ={1,2,3,4}; //数组大小根据初始化列表指定
char v3[2] ={'a','b',0}; //错误:太多的初始化值了
char v3[3] ={'a','b',0}; //正确

第四章

  • 段错误与栈溢出

       在可执行文件中,一般有如下几个段:

  1. 正文段:储存指令
  2. 数据段:储存已初始化的全局变量
  3. BSS段(Block Started By Symbol):储存未赋值的全局变量所需的空间, 起一个占位符作用,不占用可执行文件空间。
  4. 堆栈段:一般在运行时创建

      各个段在运行时,都有自己的内存空间,如果越界访问,就会出现段错误。 而函数中的局部变量都存在于堆栈段中,所以一般较大的数组应该定义为全局变量,以节省堆栈段空间,防止栈溢出。