第1章 快速上手

1.1.1 空白和注释

  程序的空白的作用: 空行将程序的不同部分分割开来;制表符缩进语句,可以更好地显示程序的结构等等。
 
  软件最大的开销并非在于编写,而是在于维护,所以需要注释。但要注意编写正确的注释,以后修改代码时也要注意注释的更新。注释如果不正确,那还不如没注释。有时候使用//符号来注释一段代码,如果在要注释的这段代码内部就有//注释存在,就会导致有一部分代码不能被注释。更好的办法使用#if指令,如下所示:

#if  0
    statements
#endif

1.1.2 预处理指令

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_COLUMN 20
#define MAX_ROW 30

  上面的5行则为预处理指令,因为它们是由预处理器解释的。预处理器读入源代码,根据预处理指令对其进行修改,然后把修改后的源代码递交给编译器。在上面的例子程序里,预处理器就用名叫stdio.h的头文件的内容替换第一条#include指令语句,其结果就仿佛是stdio.h的内容被逐个写到源文件的那个位置。
 
  另一个预处理指令是#define,它把名字MAX_COLUMN定义为20,当这个名字出现在源文件的任意位置时,它将被替换成定义的值20。宏一般都大写,用于提醒它们并不是普通的变量。
 
stdio.h头文件使我们可以访问标准I/O库(Standard I/O Library)中的函数,这组函数用于执行输入和输出。

1.1.3 gets、puts、getchar、putchar、strncpy函数示例讲解

char str[20];
while( gets(str) != '\0' )
{
    //printf("out=%s\n",str);
    puts(str);
}

  gets函数从标准输入读取一行文件,并将它存储于str数组中。一行输入由一串字符组成,以一个换行符结束。gets函数丢弃换行符,并在该行的末尾存储一个NUL字符。(注意不是NULL字符)。
  puts函数输出字符串。

函数原型: char *gets(char *buffer);     int puts(const char *str);

 
  字符串常量"hello"在内存中占6个字节的空间,按顺序分别是h、e、l、l、o和NUL。

NUL是ASCII字符集中 '\0' 的名字,而NULL是一个其值为0的指针,它们都是整型值,其值都为0,所以可以互换使用,但最好不要互换使用。
符号NULL在头文件中stdio.h中定义,但并不存在预定义的NUL字符,所以要使用必须自行定义。(#define NUL '\0')

char ch;
while( (ch=getchar())!=EOF && ch!='\n' )
    putchar(ch);

  getchar从标准输入读取一个字符并返回它的值。如果输入中不再存在任何字符,函数就会返回常量EOF.
常量EOF在stdio.h,用于提示文件的结尾。
函数原型: int getchar(void); void putchar(char ch);

char *strncpy(char *strDest,const char *strSource,size_t size);  复制strSource的size个字节到strDest

1.2 问题

 

  1. C语言并不对数组下标越界进行检查,你觉得为什么这个明显的安全手段会从语言中省去?
      1、为了提高运行效率,不检查数组下表越界,程序就可以跑得快。因为C语言并不是一个快速开发语言,它要求开发人员保证所有逻辑的正确性。所以至少到目前为止,C语言是所有高级语言中速度最快,效率最高的。几乎所有对性能有苛刻要求的场合都使用C语言。
     
      2、不检查下标是为了给程序员更大的空间,也为指针操作带来更多的方便。如果有这个检查的话指针的功能将会大大被削弱,C的数组标识符,里面并没有包含该数组长度的信息,只包含地址信息,所以语言本身无法检查,只能通过编译器检查,而早期的C语言编译器也不对数组越界进行检查,只能由程序员自己检查确保。以及在早期的CRT函数中也不对字符串指针或数组进行越界检查,都是要求程序员确保空间足够,因此也才也才有了在VS2005之后微软提供的安全的CRT函数版本。
     
  2. 编写一个程序,从标准输入读取几行输入。每行输入都要打印到标准输出上,前面要加上行号。在编写这个程序时要试图让程序能够处理的输入行的长度没有限制。
bool enterFlag = true;
int line=0;
while( (ch=getchar())!=EOF )
{
    if(enterFlag ==true)
    {
        enterFlag = false;
        line++;
        printf("line%d:",line);
    }

    putchar(ch);
    if(ch=='\n')
        enterFlag = true;
}

第2章 基本概念

 

2.1 环境

  在ANSI C的任何一种实现中,存在两种不同的环境。第1种是翻译环境,在这个环境里,源代码被转换成可执行的机器指令。第2种是执行环境,它用于实际执行代码。
 

2.1.1 翻译

  翻译阶段由几个步骤组成,组成一个程序的多个源文件通过编译过程分别转化成目标代码(object code)。然后,各个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。
  编译过程也由几个阶段组成,首先是预处理器处理,然后是源代码经过解析,判断它的语句的意思。第2个阶段是产生绝大多数错误和警告信息的地方。随后,便产生目标代码。
 

windows继承开发环境是一个完整的独立编程工具,它包括源代码编辑器,调试器和编译器。
 

2.1.2 执行

  程序的执行过程也需要经过几个阶段。
首先,程序必须载入到内存中。
然后,程序的执行便开始,调用main函数。
接着,便开始执行程序代码。在绝大数机器里,程序将使用一个运行时堆栈,它用于存储函数的局部变量和返回地址。程序同时也使用静态内存,存储静态变量。
最后就是程序的终止,它可以由多种不同的原因引起。正常终止就是mian函数返回。也可能是由于在执行过程中出现错误而自行终止。

2.2 语法规则

2.2.1 字符

? 在书写连续多个问号时使用,避免它们被解释为三字母词。
" 用于表示一个字符串常量内部的双引号。
' 用于表示字符常量'。
\ 用于表示一个反斜杠,防止它被解释为一个转义序列符。

2.2.2 标识符

  标识符就是变量、函数、类型等的名称,它们由大小写字母、数字和下划线组成,但不能以数字开头。关键字由系统保留,不能作为标识符使用。
C语言区分大小写,所以A和a是2个不同的标识符。
 

2.2.2 常用ASCII码

ASCII码值为0的对应字符为空字符' ',对应代码为NUL,对应转义字符为'\0'。
回车,ASCII码13,转义字符为'\r'
换行,ASCII码10,转义字符为'\n'
空格,ASCII码32,字符为' '
字符0,ASCII码48
字符A,ASCII码65
字符A,ASCII码97

第3章 数据

 

3.1 基本数据类型

  在C语言中,仅有4种基本数据类型-整型、浮点型、指针和聚合类型(数组和结构体等)。
 

3.1.1 整型家族

  整型家族包括字符、短整型、整型和长整型,它们都分为有符号(signed)和无符号(unsigned)两种版本。
  下面为一些类型的数值范围(以32位编译器为例):

    char    -128 - 127
    short   -2^15 - 2^15-1(-32768 - 32767)
    int       -2^31 - 2^31-1
    long double       -2^65 - 2^65-1
    unsigned char   0 - 255
    unsigned int      0 - 2^32-1

 
  一、整型变量值
  字面值这个术语是字面值常量的缩写--这是一种实体,制定了自身的值,并且不允许发生改变。整型字面值的缺省类型可以添加后缀来改变,在整型字面值后面添加字符L或l(字符l),可以使字面值类型被解释为long整型,添加字符U或u,则被解释为unsigned整型。表示整型字面值的方法有很多,其中最自然的方式是十进制整型值,例如:123 65536
 
  二、枚举类型
  枚举类型就是指它的值为符号常量而不是字面值的类型,它们以下面这种形式声明:

enum  Jar_Type {CUP , PINT , QUART , GALLON};

  声明为枚举类型的变量实际上是整型,所以可以给Jar_Type类型的枚举变量赋诸如-623这样的字面值,但最好不要这么做。
 

3.1.2 浮点类型

  浮点字面值在缺省情况下都是double类型的,除非它的后面跟一个F或f表示它是float类型的值。
 

3.1.3 指针

  变量的值存储于计算机的内存中,每个变量都占据一个特定的位置。每个内存位置都由唯一的地址确定并引用,就像一条街道上的房子由它们的门牌号码占据一样。指针只是地址的别名而已。指针变量就是一个其值为另外一个变量地址的变量,可以通过指针的值,即指向变量的地址,来访问指向的变量。

3.2 基本声明

 

3.2.1 隐式声明

  函数如果不显式地声明返回值的类型,它就默认返回整型。
 

3.3 typedef

示例:typedef char uint8 , 把标识符uint8作为char类型的别名。
应该使用typedef而不是#define来创建新的类型名,因为后者无法正确地处理指针类型,例如:

#define    ptr_char    char*
ptr_char    a,b;

相当于char *a,b; 只正确地声明了a,但是b却被声明为一个字符。

3.4 常量指针和指针常量的区别

常量指针:如果在定义指针变量的时候,数据类型前用const修饰,被定义的指针变量就是指向常量的指针变量,指向常量的指针变量称为常量指针,格式如下

int a,b;
 const int *p=&a //常量指针
//那么分为一下两种操作
p=&b;    //OK
*p=9;    //ERROR

指针常量:顾名思义它就是一个常量,但是是指针修饰的。

int a,b;
int * const p=&a //指针常量
//那么分为一下两种操作
p=&b;    //ERROR
*p=9;    //OK

3.5 存储类型

有三个地方可以用于存储变量:普通内存、运行时堆栈、硬件寄存器。
关键字register可以声明寄存器变量,但如果有太多的变量被声明为register,编译器只选择前几个实际存储于寄存器中,其余的就按普通自动变量处理。

[C和指针] 1-快速上手、2-基本概念、3-数据的更多相关文章

  1. <c和指针>学习笔记1之快速上手和基本概念

    1 c语言中的注释 功能:使这段代码在程序中不起作用,当然如果是功能注释,那是方便其他人阅读您的代码. 大部分情况下,多行的注释,我们采用的是这种方式,例如  /*内容*/. 这个符号不能嵌套,也就是 ...

  2. 快速上手系列-C语言之指针篇(一)

    快速上手系列-C语言之指针篇(一) 浊酒敬风尘 发布时间:18-06-2108:29 指针的灵活运用使得c语言更加强大,指针是C语言中十分重要的部分,可以说指针是C语言的灵魂.当然指针不是万能的,但没 ...

  3. Objective-C快速上手

    最近在开发iOS程序,这篇博文的内容是刚学习Objective-C时做的笔记,力图达到用最短的时间了解OC并使用OC.Objective-C是OS X 和 iOS平台上面的主要编程语言,它是C语言的超 ...

  4. [Full-stack] 快速上手开发 - React

    故事背景 [1] 博客笔记结合<React快速上手开发>再次系统地.全面地走一遍. [2] React JS Tutorials:包含了JS --> React --> Red ...

  5. 【opencv入门篇】 10个程序快速上手opencv【下】

    导言:本系列博客目的在于能够在vs快速上手opencv,理论知识涉及较少,大家有兴趣可以查阅其他博客深入了解相关的理论知识,本博客后续也会对图像方向的理论进一步分析,敬请期待:) 上篇传送:http: ...

  6. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  7. 快速上手Unity原生Json库

    现在新版的Unity(印象中是从5.3开始)已经提供了原生的Json库,以前一直使用LitJson,研究了一下Unity用的JsonUtility工具类的使用,发现使用还挺方便的,所以打算把项目中的J ...

  8. [译]:Xamarin.Android开发入门——Hello,Android Multiscreen快速上手

    原文链接:Hello, Android Multiscreen Quickstart. 译文链接:Hello,Android Multiscreen快速上手 本部分介绍利用Xamarin.Androi ...

  9. [译]:Xamarin.Android开发入门——Hello,Android快速上手

    返回索引目录 原文链接:Hello, Android_Quickstart. 译文链接:Xamarin.Android开发入门--Hello,Android快速上手 本部分介绍利用Xamarin开发A ...

随机推荐

  1. bzoj 1005 [HNOI2008] 明明的烦恼 (prufer编码)

    [HNOI2008]明明的烦恼 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5907  Solved: 2305[Submit][Status][Di ...

  2. 基于端口的信息探测-portscan-1.0

    http://www.tiaozhanziwo.com/archives/174.html

  3. Oracle中,利用sql语句中的函数实现保留两位小数和四舍五入保留两位小数

    Oracle中,利用sql语句中的函数实现保留两位小数和四舍五入保留两位小数: select trunc(1.23856789,2) from dual round(m,n) 可以四舍五入 trunc ...

  4. JAVA调用动态链接库(dll)

        菜鸡爬坑 基础知识  因为某个东西的keygen我只会在win下生成!! 所以只能出此下策!!之前一直是android下用jni调用so文件,现在试下java在win平台下调用dll 首先还是 ...

  5. [转]Attribute在.net编程中的应用

    Attribute在.net编程中的应用(一) Attribute的基本概念 经常有朋友问,Attribute是什么?它有什么用?好像没有这个东东程序也能运行.实际上在.Net中,Attribute是 ...

  6. 我的arcgis培训照片9

    来自:http://www.cioiot.com/successview-547-1.html

  7. 冲刺Offer - 二叉树的深度

    https://www.nowcoder.net/practice/435fb86331474282a3499955f0a41e8b?tpId=13&tqId=11191&tPage= ...

  8. 001 Cisco router prewired

    Cisco router 预配: Router>en Router#config t Enter configuration commands, one per line.  End with ...

  9. AutoCAD如何设置线宽

    一般要求粗实线粗实线0.4,细实线0.2mm. 1 先打开图层特性管理器,新建一个图层,专门放粗实线(我起名叫"我的粗实线",颜色设置为紫色,线宽为0.4mm),此前的乱七八糟的图 ...

  10. Lua中..和#运算符的用法

    Lua中..和#运算符的用法 样例 试试以下的样例就明确了在Lua编程语言提供的其它运算符: a = "Hello " b = "World" print(&q ...