重拾C语言---读C和指针一书的收获(1)

不得不大赞这本《C和指针》一书,不愧是2014年最畅销书籍之一,作者很负责,而且,每一页你都可以发现自己需要学习的地方,真心不错,就决定写博客来记录我阅读这本书的收获。

一,注释

  在C中,如果你用/*   */来注释掉一段代码,你不一定能如愿,如果,这段代码内部原先就有注释存在,这样子就会出现问题。

  要从逻辑上删除一段C代码,最好的办法是用#if指令

  #if 0

     statement

  #endif

  这样子statement就可以有效的从程序中去掉

二,预处理指令

  #include 头文件

  如果你有一些声明需要用于几个不同的源文件,这个技巧也是一个简便的方法----你在一个单独的文件中编写这些声明,然后用#include指令把这个文件包含到需要使用这些声明的源文件中,避免了复制。

  int read_column_numbers(int column[] , int max);

  像这样子的声明叫做函数原型,其中的参数名称并非是必要的。

  void rearrange( char *ouput,char const *input,int columns, int const column[]);

  这个函数里面的参数中,第二个和第四个被声明为const,说明函数将不会修改函数调用者所传递的这个两个参数

  提示:假如这个程序的源代码由几个源文件组成,那么使用该函数的源文件都必须写明该函数的原型,把原型放在头文件中并使用#include指令包含他们,可以避免由于同一个声明的多份拷贝而导致的维护性问题

  个人补充:

  常见extern放在函数的前面成为函数声明的一部分,那么,C语言关键字extern在函数的声明中起什么作用?

  答案与分析:

  如果函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。即下述两个函数声明没有明显的区别:

  extern int f(); 和int f();

  当然,这样的用处还是有的,就是在程序中取代include “*.h”来声明函数,在一些复杂的项目中,我比较习惯在所有的函数声明前添加extern修饰。

三:gets函数

  gets函数从标准输入读取一行文本并把它存储于作为参数传递给他的数组里,一行输入由一串字符组成,以一个换行符结尾,gets函数丢弃换行符,并在末尾存储一个nul字节(nul字节是指字节模式全为0的字节,类似于‘\0‘这样的字符常量),然后gets函数返回一个非nul值,表示该行已经被成功读取,如果不存在输入行,它就返回null值

四:字符串

  C语言不存在string数据类型,但是整个语言中有一个约定:字符串就是一串以nul字节结尾的字符

五:

  int read_column_numbers(int columns[], int max){...}

  在函数声明的数组参数中,并没有指定数组的长度,这是正确地,因为不论调用函数的程序传递给它的数组参数的长度是多少,这个函数都照收不误,这是一个伟大的特征,允许函数操纵任意长度的一维数组,这个特征的不利的一面是函数无法知道该数组的长度,如果确实需要知道数组的长度,他的值必须作为一个单独的参数传给函数

六:scanf函数

  scanf("%d",&columns[num])

  scanf函数接受几个参数,第一个参数时一个格式字符串,用于描述期望的输入类型,剩余几个参数都是变量,用于存储函数所读取的输入数据。

  scanf函数的返回值是函数成功转换并存储与参数中的值的个数

  scanf函数使用所有格式码(除了%c之外)事,输入值之前的空白都会被跳过,值后面的空白表示该值结束,因此,用%s格式码输入字符串时,中间不能包含空白

  如上述例子,scanf函数转换了一个整数之后,它就会返回1这个值

七:数组

  标准并未硬性规定C编译器对数组下标的有效性进行检查,所以,为了避免数组数据溢出破坏后面存储单元中的数据,要人为的进行限制:num < max,保证输入的数组最多只能有max个。

八:puts函数

  puts函数是gets函数的输出版本,它把指定的字符串写到标准输出并在末尾添上一个换行符

  exit(EXIT_FALURE)  是终止程序运行,EXIT_FAILURE这个值被返回给操作系统,提示出现错误

九:分析下面这行代码

  int i;

  .......

  while((i=getchar())!=EOF && i!=‘\n‘)

    ;

  getchar函数从标准输入读取一个字符并返回他的值,如果输入中不再存在字符,则返回EOF

  在大多数其他语言中,我们将像下面这个样子写循环

  i = getchar();

  while(i!=EOF && i = ‘\n‘)

   i=getchar();

  他将读取一个字符,接下来,如果我们尚未到达文件末尾或者读取的字符并不是换行符,他将继续读取下一个字符

   其实上面两种写法是等价的,C语言运行将赋值操作蕴含于while语句内部,这样就允许程序员消除冗余语句

  i 被声明为整型而不是char的原因是EOF是一个整型值,他的位数比char要多

  对于该语句的最后一点说明是,while语句后面单独的一个分号称为一个空语句

十:strncpy函数

  strncpy函数的前两个参数分别是目标字符串和源字符串地址,第三个参数是指定需要复制的字符数

  字符串最后要加一个Nul字符作为终止符

十一:警告总结

  1.在scanf函数的标量参数前未添加&字符

  2.机械地把printf函数的格式代码照搬与scanf函数

  3.在应该使用&&的地方用了&

  4.误用了=而不是==

十二:编程提示的总结

  1.使用#include指令避免重复声明

  2.使用#define指令给常量值取名

  3.在#include文件中放置函数原型

  4.在使用下标前先检查他们的值

  5.在while或If表达式中蕴含赋值操作

  6.如何编写一个空循环体

  7.始终进行检查,确保数组不越界!!!!

  

  

时间: 2024-10-11 06:07:45

重拾C语言---读C和指针一书的收获(1)的相关文章

编程成长日记——重拾C语言

人生总是需要一个契机才会去改变,其实与其说是契机,也不过是自己再给自己一次机会而已. 重拾C语言,我决定再给自己一次机会,不知道多年以后的我再次翻看这篇博客的时候会是怎样的心情,会不会记得当下身为大三狗的我终于想要告别一事无成,一无所获,一败涂地的颓废而不自知的大学生活,我不想说是为了理想而奋斗,更不是为了中华崛起,只是为了我自己,仅此而已. 感谢比特,给我一次改变的机会. 从零开始学起C语言. --------------------------------------煽情分割线-------

重拾c语言之动态内存分配

动态内存分配 传统数组的缺点: 1数组长度必须事先制定,且仅仅能是长整数不能是变量 2传统形式定义的数组该数组的内存程序无法手动释放 3数组一旦定义,系统就会为该数组分配的存储空间就会一直存在直到该函数执行结束 4数组的长度不能再函数的执行的过程中动态的扩充或者缩小 5不能跨函数使用 为什么须要动态分配内存 动态内存分配内存举例--动态数组的构造 静态内存分配和动态内存分配 跨函数使用内存的问题 #include<stdio.h> void f(void) { int a[5]={0,1,2,

编程成长日记——重拾C语言&lt;二&gt;

关于按位与&和逻辑右移>> 求一个数的二进制的时候,可以采用这种方法,向右移一位,相当于除以二,所以有以下代码: #include<stdio.h> //求一个数的二进制  int main()  {     char arr[32];    int num=0;    int i=0;    printf("请输入一个数字:");    scanf("%d",&num);    for(i=0;i<32;i++)   

【重拾】数据结构之一

前言 久违来一发,回来学校也都两周了,想想也该定下来学学点什么了,突然发现以前学的好像都已经忘的差不多了,而且以前学的也学得云里雾里,所以今天我要重拾数据结构. 何为数据结构 数据是描述客观事实的数和字符的集合,人们通常以数据元素作为数据的基本单位,比如52班的每个学生记录都是一个数据元素数据项是具有独立含义的最小数据单位. 数据结构是指所有数据元素已经数据元素之间的关系数据结构包括以下几个方面:    1.数据元素之间的逻辑关系,即数据的逻辑结构,它是数据结构在用户面前呈现的形式    2.数

重拾linux

重拾linux 起因 因为想重拾起linux,同时需要用docker起几个镜像,用来学习网络知识.本来想直接去阿里云上买,后来一想自己机器上,起一个linux是个不错的选择,毕竟不花钱! 还可以用来做本地测试,学习使用linux.docker等.记录下过程,防止以后忘记!(所以不会涉及具体的安装步骤) 下载 到网易开源镜像站,挑选一个linux下载.我安装linux只要是为了学习运维方面的知识,同时用于进行网络知识方面的实践.如果你跟我一样,推荐Ubuntu server版本,纯字符界面,就跟一

嵌入式 Linux C语言(九)——C语言的安全问题和指针陷阱

嵌入式 Linux C语言(九)--C语言的安全问题和指针陷阱 C语言是灵活度和自由度较大的编程语言,作为C语言核心的指针更是让C语言程序员可以越过安全的栅栏,对某些内存区域进行破坏性访问,引发安全风险.很多安全问题都能追根溯源到指针的误用.本文将从指针的角度解读C语言常见的安全问题和指针陷阱. 一.指针的声明和初始化 1.不恰当的指针声明 int* ptr1, ptr2;//声明ptr1为int指针,ptr2为整型 int *ptr1, *ptr2;//ptr1,ptr2都声明为指针 #def

重拾qt

最近公司又接了一个煤矿的项目,要写个小程序摘取数据,我是公司唯一c++程序员,本来搞ios搞好好的,现在又得重拾半年没摸得qt了.呵呵...呵呵呵. 这里只记录这次小程序的一些小的总结吧.. 1.中文字符: 函数:把一般字符串转为中文字符串: //中文处理 QString mysqlServerTs:: handleTheChinesCode(const char*words){ QTextCodec* tc = QTextCodec::codecForLocale(); return tc->

重拾C/C++基础

1.复制指针时只复制指针中的地址,而不会复制指针指向的对象2.解决护栏柱错误的根本 是 从思想认知上搞定. 数组的序号为偏移量.  也即: 数组的第一个元素为arrName[0],其偏移量为03.使用strcpy函数时要注意,若是源串的长度大于目标串的长度,将会覆盖缓冲区后面的内容  所以尽量使用strncpy来替代strcpy4.数组可以使一维或者是多维.只要数组包含的元素为内置类型或者有默认构造函数的类,就可以初始化5.数学运算符有5个: +(加) -(减) *(乘) /(除) %(求模)6

【玩转SQLite系列】(一)初识SQLite,重拾sql语句

转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53230842 本文出自[DylanAndroid的博客] [玩转SQLite系列](一)初识SQLite,重拾sql语句 SQLite由于是一个轻型的嵌入式的数据库,被应用于Android系统当中.在Android开发中 我们难免会用到SQLite数据库.接下来用一系列的文章来数据一下SQLite数据库. 一.认识SQLite 1.什么是SQLite SQLite,是一款轻型