C语言速成手册(一):基本数据类型、标准输出、函数

Via http://www.matrix67.com/blog/article.php?id=262 by Matrix67

目录:
C语言速成手册(一):基本数据类型、标准输出、函数
C语言速成手册(二):布尔值、条件判断、循环
C语言速成手册(三):数组、字符串、结构
C语言速成手册(四):指针、动态内存分配、标准输入
C语言速成手册(五):其它运算符、文件操作、其它函数
C语言速成手册(六):其它问题、后记

语句和语句块
    和Pascal一样,C语言的每条语句以分号结尾。
    和Pascal一样,单词和语句间的空格、回车符对编译没有影响。
    C语言的语句块用花括号标识,也就是说字符 { 相当于Pascal的begin,字符 } 相当于Pascal的end; 。语句块中最后一条语句末尾的分号不能省略。

    如果语句块里只有一条语句,语句块的标识可以省略。这就好像Pascal代码:


    里面的begin和end可以省略一样。

注释的写法
    两种情形被认为是注释。符号// 的后面(只限一行),以及符号 /* 和 */ 之间(可以跨行)。例如:
 

常用数据类型
C                  |  Pascal
——————-+————
short              |  shortint
int                |  integer
long               |  longint
long long          |  int64
unsigned short     |  byte
unsigned int       |  word
unsigned long      |  dword
unsigned long long |  qword
float              |  real
double             |  double
char               |  char

定义变量
    定义变量使用这样的格式:
类型名 变量名1, 变量名2, … , 变量名n;
    变量名的命名规则与Pascal相同:只能用大小写字母、数字或下划线,第一个字符不用数字。所不同的是,C语言中定义的名称要区分大小写。
    例如,下面的两条语句定义了三个整型变量和一个字符变量。
int a,b,c;
char ch;
    和
Pascal不同,变量的声明不一定要在整个代码前。你可以在程序中任意一个地方定义一个新的变量。定义的变量只能在当前函数(中的当前语句块)后面的代
码中使用。也就是说,不同函数之间的变量不能混用,在某循环里定义的变量在循环外面是无效的。定义在函数外的变量将作为全局变量供后面的函数使用。

定义常量
    为了告诉编译器某个变量不会改变,你可以在变量定义前加一个const。例如,下面的语句定义了一个常数:
const int maxn=2000;

基本数学运算
  作用   |  C  | Pascal
———+—–+———–
   加    | +   |  +
   减    | –   |  –
   乘    | *   |  *
   除    | /   |  / 或 div
  取余   | %   |  mod
    除法的结果是整数还是小数取决于参与运算的数是整数还是小数。10 / 4等于2,但写成 10.0 / 4 或 10 / 4.0 就得2.5了。

关于字符类型
    C语言中的字符用一对单引号' '标注。例如,'A'表示字符A。
    无法打印或可能产生冲突的字符用反斜杠加一个字符来表示,这叫做转义符。常用转义符如下:
\n  换行
\t  Tab
\a  响铃
\"  双引号
\'  单引号
\?  问号
\\  反斜杠
    因此,'\''表示一个单引号,虽然它看上去像是两个字符。

    字符类型可以依照ASCII码进行数学运算。例如,字符变量ch可能被赋值为'A'+2(这样ch就等于'C'),而'0'+'1'则等于'a'。

C语言中的赋值
    和Pascal不一样,C语言的赋值只用一个等号,等号前没有冒号。
    声明变量时后面可以跟一个等号赋初始值。
    下面的语句都是合法的:

类型转换与“名词动用”
    C语言中,不同类型的变量可以相互赋值,程序将自动转换类型(即使是数字与字符之间)。
    C语言中也存在“使动”用法(类似于Pascal中使用int64(a)扩展变量长度的用法)。假如a是整型,(double)a表示“实数版的a”;假如ch是一个字符,(int)ch就相当于Pascal中的ord(ch)。
    考虑下面的代码:

    这段代码中,a最终被赋值为122,b得到的值是20,而c的值则为字符'0';d获得的值为6.0,而e的值是6.1 。

标准输出
    输出使用printf函数。printf函数的使用方法如下:
printf (字符串, 待输出表达式1, 待输出表达式2, … , 待输出表达式n );
    C
语言的字符串用一对双引号"  "注明,里面允许有转义符。printf将把字符串输出到屏幕上。字符串中可以有若干个标识,这些标识帮后面待输出的内容
“占一个位置”。常用的标识格式为%[x][.y](c|d|f|e),其中x表示输出占的宽度,y表示保留位数;c,d,e,f四个字母表示输出类型,
你需要选择一个。c表示输出字符,d(也可以用 i
)表示输出整数,f表示输出小数,e用科学计数法表示小数。printf后面的参数依次“填入”这些标识。注意d和e,f不能混用,也就是说,你不能把一
个小数输出成整数格式,或把整数输出成小数格式(除非事先转了类型)。
    特别地,%%表示输出一个百分号。

    观察下列代码片段

    程序输出的结果为:
Welcome to Matrix67.com
4 + 5 = 9
and 4 – 5 = -1

2 * a = 00204
2 * a = 204.000000
2 * a =      204
2 * a =    00204
a = 'f'

a / b = 14.571429
a / b = 1.457143e+001
a / b = 14.571428571
a / b = 14.571
a / b =   14.571
b / a = 6.863%

c = A
c =   A
c = 65
Matrix67.com

函数的定义、返回和调用
    定义一个函数的格式如下:
函数返回类型 函数名( 参数类型1 参数名1, 参数类型2 参数名2, … , 参数类型n 参数名n )
{
    函数内容
}
    如果某个函数不返回任何数据(相当于Pascal中的“过程”),函数返回类型要写成void。如果不写返回类型,函数默认返回类型为int。
    如果某个函数不带任何参数,参数表一般留空(也可以用一个void代替)。
    为了强调某个参数在整个函数中始终不变,类型前可以标明const。

    函数的返回使用下面的语句:
return 表达式;
    执行这条语句将立即终止该函数的运行。

    下面定义的一个函数可以返回三个数的平均值:

    C语言也支持函数的内联,方法是在函数返回类型前加inline。例如:

    函数的调用方法和Pascal一样。如果调用函数所带的参数类型和定义的不一样,程序会自动转换类型。下面的语句合法地调用了刚才定义的函数:
num = average( 2, 6.5, 4.23 );
    有一点不同的是,当所调用的函数不带参数时仍然要写括号,例如:

    C
语言同样支持递归调用。由于C语言也只能调用前面定义过的函数,因此C同样需要类似于向前引用的方法。具体方法是把需要提前引用的函数的第一行复制一份提
到前面去。下面的两种做法都是正确的,其中第一种方法允许在output函数里调用后面的average,第二种则允许在这句话后面的所有函数中调用它。

    事实上,向前引用时参数名已经没有意义,因此参数名可以省略,直接写成这样:
double average (double , double , double );

    C语言中也允许在函数中定义子函数(函数的嵌套)。标准的C语言不支持在函数中定义子函数(函数的嵌套),虽然某些编译器可能支持。

一个完整的程序代码的构成
    代码前几行用于包含头文件,每行包含一个,格式如下:
#include <头文件名>
    常
用的头文件有stdlib.h, stdio.h, string.h,
math.h等等,分别提供一些常用函数、输入输出函数、字符串函数和数学相关函数。注意我们之前用的printf函数是属于stdio.h里的,因此要
使用该函数必须在代码最开头加入#include <stdio.h>。
    接下来是若干个函数。这些函数里必须有一个名为main的函数,它返回的值是一个int类型,代表程序的退出代码(0=正常退出)。程序会自动寻找这个函数作为主函数执行。

    下面的代码是一个完整的C程序代码,这是我们的第一个完整的程序代码:

 

 

C语言速成手册(零):序言、环境、你的第一个程序

Via http://www.matrix67.com/blog/archives/215

本文目的:介绍C语言最基本的用法,能对付NOIp就行
本文特点:没有废话,不讲概念,只介绍语法
适宜读者:已经学过其它语言,希望学习C语言的人;特别适合熟练Pascal并想转用C语言的OIer
编程环境:就我个人而言,Windows下用Dev-C++,Linux下用Emacs

继续阅读

【搬迁】单步跑过BlogEngine的Trackback——系统调试&Trackback介绍

用BlogEngine的代码扒了下Trackback的代码直接搬到了Librazyframe上,结果根本跑不起来:

System.Net.WebException: 请求被中止: 请求已被取消。 —> System.IO.IOException: 在写入所有字节之前不能关闭流。

在写入所有字节之前不能关闭流?好像用到流的只有

整了半天,决定跑单步调试。根据 BlogEngine.Net架构与源代码分析系列part7:Web2.0特性——Pingback&Trackback找到了入口点SendPing.cs

“实际上SendPings类是BlogEngine.Net的一个Extension(类具有Extension特性,这个后面会有专门的一篇文章来讲解),它监听了Page.Saved和Post.Saved”

PostSaved监听Page.Saved和Post.Saved,当并非删除、无动作或不公开时,异步执行Ping(item, url)

Ping方法睡两秒(为什么?),执行PingService.Send(itemUrl);和Manager.Send(item, itemUrl);

这就是真正的入口了。

f12到Manager.cs

首先尝试发送Trackback,未成功则发送Pingback。不过GetTrackBackUrlFromPage好像不识别WordPress的rel="trackback",只认Trackback:Ping

继续F12,到了Trackback.cs

30行完全把中文置于不顾,这就是开头的异常产生的原因。(行号以所贴代码计算)

修改一下,开始单步

注释以下几行

SendPing.cs 38,41 Thread.Sleep(2000); PingService.Send(itemUrl);

修改Trackback.cs

发起请求了

一堆设置,应注意的是application/x-www-form-urlencoded这是,Trackback的格式

这是我修改后的写入,真正的核心代码实际上就只有message.ToString(),进去看看

真正我们要发送的就是“title=xx&url=xx&excerpt=xx&blog_name=xx”,

  title – 文章的标题

  excerpt – 文章的摘要。在Movable Type系统中,如果摘录信息超过255个字符将会被截断为252个字符,并在后面增加…三个字符

  url – 文章的永久连接。象其它永久连接一样,这个连接应可能准确地在页面中定位文章的入口,因有疑问时这个链接会用到

  blog_name – 发表文章的blog的名称

而这些参数,是在Manager.cs 17传入的(BlogName是BlogSettings.Instance.Name)

把这个字符串转化为byte[]后写入请求,

获取响应(看来更改没错,测试网址马上接到了Trackback)。如果成功,响应会包含"<error>0</error>",否则失败。出了异常更不用说了。

返回后到了Manager.cs 22,如果trackbackSent为false,则发送Pingback

Pingback实现和Trackback大同小异,只不过是用了Xmlrpc而已

F5放水,结束了单步,看来BlogEngine也有挺多毛病的……不能自动发现WordPress的Trackback URL,Trackback消息不能带中文,发送Trackback或Pingback时可能无法捕获超时异常……不过BusinessBase这种状态维护方式还是挺不错的。