helloworld
cat hello.c
#include //包含标准库的信息
main() //定义名为main的函数,它不接受参数值
{ //main函数的语句都被括在花括号中
printf("hello,world\n");//main函数调用库函数printf以显示字符序列 \n代表换行符
}
\t 表示制表符;\b 表示回退符;"表示双引号
打印下列华氏温度与摄氏温度对照表
cat huashi.c
#include
/*
当fahr=0,20,… ,300时,分别
打印华氏温度与摄氏温度对照表*/
main()
{
int fahr,celsius;
int lower,upper,step;
lower = 0; /* 温度表的下限*/
upper = 300; /* 温度表的上限*/
step = 20; /* 步长*/
fahr = lower;
while (fahr <= upper ){
celsius = 5 * (fahr-32)/9;
printf("%d\t%d\n",fahr,celsius);
fahr = fahr + step;
}
}
int与float类型的取值范围取决于具体的机器。对于int类型,通常为16 位,其取值范围在-32768~32767 之间,也有用32 位表示的int 类型。float 类
型通常是32位,它至少有6 位有效数字,取值范围一般在10-38~10+38之间。
除 int与float类型之外,C语高还提供了其它一些基本数据类型,例如:
char 字符——一个字节
short 短整型
long 长整型
double 双精度浮点型
这些数据类型对象的大小也取决于具体的机器。另外,还存在这些基本数据类型的数组、结
构、联合,指向这些类型的指针以及返回这些类型值的函教。
改进版
由于我们使用的是整型算术运算,因此经计算得到的摄氏温度值不太精确,例如,与0℉对应的精确的摄氏温度应该为-17.8℃,而不是-17℃。为了得到更精确的结果,应该用浮点算术运算代替上面的整型算术运算。
cat huashi.c
#include
/*
公式℃=(5/9)(℉-32)打印下列华氏温度与摄氏温度对照表
当fahr=0,20,… ,300时,分别
打印华氏温度与摄氏温度对照表*/
main()
{
float fahr,celsius;
float lower,upper,step;
lower = 0; /* 温度表的下限*/
upper = 300; /* 温度表的上限*/
step = 20; /* 步长*/
fahr = lower;
while (fahr <= upper ){
celsius = 5.0 * (fahr-32.0)/9.0;
printf("%3.0f %6.1f\n",fahr,celsius);
fahr = fahr + step;
}
}
printf中的转换说明%3.0f表明待打印的浮点数(即fahr)至少占3个字符宽,且不带小数点和小数部分;%6.1f表明另一个待打印的数(celsius)至少占6个字符宽,且小数点后面有1位数字。
%d 按照十进制整型数打印
%6d 按照十进制整型数打印,至少6个字符宽
%f 按照浮点数打印
%6f 按照浮点数打印,至少6个字符宽
%.2f 按照浮点数打印,小数点后有两位小数
%6.2f 按照浮点数打印,至少6个字符宽,小数点后有两位小数
此外,printf 函数还支持下列格式说明:%o 表示八进制数;%x 表示十六进制数;%c表示字符;%s表示字符串;%%表示百分号(%)本身。
for循环
cat huashi2.c
#include
main()
{
int fahr;
for(fahr = 0;fahr <=300;fahr = fahr +20)
printf("%3d %6.1f\n",fahr,(5.0/9.0)*(fahr-32));
}
符号常量
cat huashi3.c
#include
#define LOWER 0
#define UPPER 300
#define STEP 20
main()
{
int fahr;
for(fahr = LOWER;fahr <=UPPER;fahr = fahr + STEP)
printf("%3d %6.1f\n",fahr,(5.0/9.0)*(fahr-32));
}
LOWER、UPPER 与STEP 都是符号常量,而非变量,因此不需要出现在声明中。符号常量名通常用大写字母拼写,这样可以很容易与用小写字母拼写的变量名相区别。注意,#define指令行的末尾没有分号。
字符输入/输出
cat copy.c
#include
main()
{
int c;
c=getchar();
while(c!=EOF){
putchar(c);
c=getchar();
}
}
cat copy1.c
#include
main()
{
int c;
while((c=getchar())!=EOF){
putchar(c);
}
}
while 循环语句首先读一个字符并将其赋值给c,然后测试该字符是否为文件结束标志。如果该字符不是文件结束标志,则执行while语句体,并打印该字符。随后重复执行while语句。当到达输入的结尾位置时,while循环语句终止执行,从而整个main函数执行结束。
字符计数
cat test/calchar.c
#include
main()
{
long nc;
nc=0;
while(getchar()!=EOF){
++nc;
printf("%ld\n",nc);
}
}
运算符++,其功能是执行加1 操作。
行计数
$ cat calline.c
#include
main(){
int c,nl;
nl=0;
while((c=getchar())!=EOF){
if(c=='\n'){
++nl;
}
}
printf("%d\n",nl);
}
编写一个统计空格、制表符与换行符个数的程序
cat cal.c
#include
main(){
int c,emptyChar,tableChar,changeChar;
emptyChar=0,tableChar=0,changeChar=0;
while((c=getchar())!=EOF){v
if(c==' '){
++emptyChar;
}else if(c=='\t'){
++tableChar;
}else if(c=='\n'){
++changeChar;
}
}
printf("空格有%d\n",emptyChar);
printf("制表符有%d\n",tableChar);
printf("换行符有%d\n",changeChar);
}
编写一个将输入复制到输出的程序,并将其中连续的多个空格用一个空格代替。
cat skipempty.c
#include
main(){
int c,temp;
while((c=getchar())!=EOF){
if(c==' '){
if(temp!=' '){
putchar(c);
}
temp=' ';
}else{
putchar(c);
temp=c;
}
}
}
编写一个将输入复制到输出的程序,并将其中的制表符替换为\t,把回退符替换为\b,把反斜杠替按为\。这样可以将制表符和回退符以可见的方式显示出来。
cat showorigin.c
#include
main()
{
int c;
while((c=getchar())!=EOF){
if(c=='\t'){
printf("\t");
}else if(c=='\\'){
printf("\\");
}else if(c=='\b'){
printf("\b");
}else{
putchar(c);
}
}
}
程序用于统计行数、单词数与字符
cat cal1.c
#include
#define IN 1 /*在单词里*/
#define OUT 0 /*在单词之间*/
main(){
int c,nc,nl,nw,state;
c=nc=nl=nw=0;
state=OUT;
while((c=getchar())!=EOF){
++nc;
if(c=='\n'){
++nl;
}
if(c==' ' || c=='\t' || c=='\n'){
state=OUT;
}else if (state==OUT){
++nw;
state=IN;
}
}
printf("共有%d个字符\n %d行\n %d个单词\n",nc,nl,nw);
}
程序执行时,每当遇到单词的第一个字符,它就作为一个新单词加以统计。state 变量记录程序当前是否正位于一个单词之中,它的初值是“不在单词中”,即初值被赋为OUT。我们在这里使用了符号常量IN与OUT,而没有使用其对应的数值1 与0,这样程序更易读。
编写一个程序,以每行一个单词的形式打印其输入
cat printw.c
#include
main(){
int c, temp;
while((c=getchar())!=EOF){
if(c==' '){
if(temp!=' '){
putchar('\n');
}
temp=' ';
}else{
putchar(c);
temp=c;
}
}
}
编写一个程序,以统计各个数字、空白符(包括空格符、制表符及换行符)以及所有其它字符出现的次数
cat cal2.c
#include
main()
{
int digest[10];
int i,c,whiteC,otherC;
whiteC=otherC=0;
for(i=0;i<10;i++)
{
digest[i]=0;
}
while((c=getchar())!=EOF)
{
if(c>='0' && c<='9')
++digest[c-'0'];
else if(c==' '||c=='\t'||c=='\n')
++whiteC;
else
++otherC;
}
printf("数字 ");
for(i=0;i<10;i++)
printf("%d ",digest[i]);
printf("\n空白字符%d",whiteC);
printf("\n其它字符%d\n",otherC);
}
函数
cat testpow.c
#include
int power(int m,int n);
main()
{
int i;
for(i=0;i<10;i++)
printf("2的%d次幂是%d, -3的%d次幂是%d\n",i,power(2,i),i,power(-3,i));
return 0;
}
int power(int m,int n)
{
int i,total;
total=1;
for(i=1;i<=n;i++)
total=total*m;
return total;
}
函数定义的一般形式为:
返回值类型函数名(0个或多个参数声明)
{
声明部分
语句序列
}
main函数的末尾有一个return语句。由于main本身也是函数,因此也可以向其调用者返回一个值,该调用者实际上就是程序的执行环境。一般来说,返回值为0 表示正常终止,返回值为非0 表示出现异常情况或出错结束条件。为简洁起见,前面的main 函数都省略了return 语句,但我们将在以后的main 函数中包含return 语句,以提醒大家注意,程序还要向其执行环境返回状态。
字符数组
cat str.c
#include
#define MAXLINE 1000
int getoneline(char line[], int lmt);
void copy(char to[], char from[]);
main()
{
int len; /*目前的长度*/
int max; /*目前为目最大的字符长度*/
char line[MAXLINE];/*当前输入的字符串*/
char longest[MAXLINE];/*当前存储的最长字符串*/
max=0;
while((len=getoneline(line,MAXLINE))>0)
{
if(len>max){
max=len;
copy(longest,line);
}
}
if(max>0)
printf("%s\n",longest);
return 0;
}
int getoneline(char line[],int lmt)
{
int c,i;
for(i=0;i < lmt-1 && (c=getchar()) != EOF && c != '\n';++i)
{
line[i]=c;
}
if (c=='\n')
{
line[i]=c;
++i;
}
line[i]='\0';
return i;
}
void copy(char to[], char from[])
{
int i;
i=0;
while((to[i]=from[i])!='\0')
++i;
}
首先,我们编写一个独立的函数getline,它读取输入的下一行。我们尽量保持该函数在其它场台也有用。至少getline 函数应该在读到文件末尾时返回一个信号;更为有用的设计是它能够在读入文本行时返回该行的长度,而在遇到文件结束符时返回0。由于0 不是有效的行长度,因此可以作为标志文件结束的返回值。每一行至少包括一个字符,只包含换行符的行,其长度为1。当发现某个新读入的行比以前读入的最长行还要长时,就需要把该行保存起来。也就是说,我们需要用另一个函数copy把新行复制到一个安全的位置。
外部变量与作用域
人们通常把变量和函数的extern 声明放在一个单独的文件中(习惯上称之为头文件),并在每个源文件的开头使用#include 语句把所要用的头文件包含进来。后缀名.h约定为头文件名的扩展名。
cat str1.h
#ifndef CTR1_H_
#define CTR1_H_
#define MAXLINE 1000
char line[MAXLINE];
int max;
char longest[MAXLINE];
int getoneline(void);
void copy(void);
#endif
外部变量时谨慎地使用了定义(define)与声明(declaration)这两个词。“定义”表示创建变量或分配存储单元,而“声明”指的是说明变量的性质,但并不分配存储单元。
cat str1.c
#include
#include "str1.h"
int getoneline(void);
void copy(void);
main()
{
int len; /*目前的长度*/
extern int max; /*目前为目最大的字符长度*/
extern char longest[];/*当前存储的最长字符串*/
max=0;
while((len=getoneline())>0)
{
if(len>max){
max=len;
copy();
}
}
if(max>0)
printf("%s\n",longest);
return 0;
}
int getoneline(void)
{
extern char line[];
int c,i;
for(i=0;i < MAXLINE-1 && (c=getchar()) != EOF && c != '\n';++i)
{
line[i]=c;
}
if (c=='\n')
{
line[i]=c;
++i;
}
line[i]='\0';
return i;
}
void copy(void)
{
extern char line[],longest[];
int i;
i=0;
while((longest[i]=line[i])!='\0')
++i;
}
前几行定义了main、getline 与copy 函数使用的几个外部变量,声明了各外部变量的类型,这样编译程序将为它们分配存储单元。从语法角度看,外部变量的定义与局部变量的定义是相同的,但由于它们位于各函数的外部,因此这些变量是外部变量。
函数在使用外部变量之前,必须要知道外部变量的名字。要达到该目的,一种方式是在函数中使用extern 类型的声明。这种类型的声明除了在前面加了一个关键字extern 外,其它方面与普通变量的声明相同。
某些情况下可以省略extern 声明。在源文件中,如果外部变量的定义出现在使用它的函数之前,那么在那个函数中就没有必要使用extern声明。因此,main、getline及copy中的几个extern 声明都是多余的。在通常的做法中,所有外部变量的定义都放在源文件的开始处,这样就可以省略extern声明。