在有C++基础的前提下,学习C语言,使用了《C程序设计》(第四版)(谭浩强)这本书,了解一下C语言的基础知识。
前言
——学习《C程序设计(第四版)》(谭浩强)的原因及感想
以前没有接触过C语言,都是直接学习C++过来的,然后,看见有些程序在编写的时候,会汲及到那么一两个关于C语言的知识点,但又很多人说,学习了C++的话,就不用学习C语言了,只是,自己还是想系统地了解学习一下,真正地体会一下,我想,从C++转型到学习C语言话,也没有什么难度吧,而且打算粗学,没有打算精学,没打算专攻C语言,只是想了解一下最基本的语法那些,于是,不断地上网找资料,还是决定了购买《C程序设计(第四版)》——谭浩强,用这本书来学习,在2011.12.06和2011.12.07这两天,竟然大概总共只花了五个小时的时候,就将这本书刷完了,刷了一次以后才发觉,原来C++和C语言如果不深研它的话,还真的是大同小异,要说不同,就只有那么几个地方,输入输出语句(包括字符输入输出,文件的输入输出,屏幕的输入输出),类的使用,C语言的类就是结构体,比C++的类简单多了...
只是,在看谭的这本书的时候,发觉还有另外一个收获,基于这个原因,所以今天(2012.01.12)就再次开始翻阅这本书,因为还没有做总结,上次看过的也没有很深的印象,其中发觉,main的函数参数调用,define与const,程序设计思想,这本书里面的这几个点,对于个人来说,挺有价值的,我想再复习重温一下,顺便再做一些小题目练练手,前段时间一直在复习大学各科的东西,也很久没有写过程序了,好吧,不多说,开工。
第01章
——程序设计和C语言
第一章,跳得很快啊,理解性的东西不多,需要记忆的东西,还是记录一下吧,挑一些经典的易忘的,呃,好像只有一个值得记录。
100. 程序设计的任务
101. 程序设计,是指从确定任务到得到结果、写出文档的全过程。
102. 程序设计经典的五过程:
1021. 问题分析 -> 设计算法 -> 编写程序 -> 对源程序进行编辑、编译和连接 -> 运行程序,分析结果
第02章
——算法,程序的灵魂
200. 怎样表示一个算法
202. 用流程图表示算法
第03章
——顺序程序设计
在第03章中,这本书主要介绍了编写一个顺序程序需要掌握的基本知识,其中包括数据的类型介绍,各运算符的介绍,这些规则基本与C++语言无差异,至于第四节的时候,讲述的是数据的输入与输入,这部分与C++语言有较大差异,需要认真看看,学习一下语法。
301. 有关数据输入输出的概念
3011. 所谓输入输出是以计算机主机为主体而言的。
3012. C语言本并不提供输入输出语句,输入和输出操作是由C标准函数库中的函数来实现的。
3013. C语言中的标准输入输出函数主要有putchar,getchar,printf,scanf,puts(字符串),gets(字符串).
3014. C语言中,标准输入输出函数标准库头文件为stdio.h (standard input & output),这与C++的不同点。
3015. 简单过一下putchar和getchar的使用。
----30151. char a; a = getchar(); 输入’字符’,然后按回车,’字符’会被送到变量a处。(getchar能接收回车\n)
----30152. char b = ‘o’; putchar(b); 将会在屏幕上输出字符’o’.
3016. printf与scanf的使用.(详细例子应用见本章习题)
----30161.printf的使用.
----------#include
----------int printf( const char *format, ... );
----------printf()函数根据format(格式)给出的格式打印输出到STDOUT(标准输出)和其它参数中.
----------字符串format(格式)由两类项目组成 - 显示到屏幕上的字符和定义printf()显示的其它参数.
----------即 printf函数的一般格式为:print(格式控制,输出表列).
----------格式声明一般形式为: % 附加字符 格式字符
----------常用格式字符有:d (整型带符号), c(字符型),f(浮点型). %%(输出’%’);
-------------如:当int a = 0; printf(“a = %d”, a); 将输出a = 0.
----------附加字符有: -m.n 指占m列,其中包含n个小数位,(-)左对齐.
-------------如:当 float a = 123.678; printf(“a = %-8.2f”, a); 将输出 a = |123.68 |(占8位, ”|”仅用于辨认)
-------------如:当 float a = 123.678; printf(“a = %8.2f”, a); 将输出 a = | 123.68|(占8位,右对齐)
-------------如:当 float a = 123.678; printf(“a = %.1”, a); 将输出 a = |123.7|(字符紧凑合在一起)
----30162. scanf的使用.
----------#include
----------int scanf( const char *format, ... );
----------实际上,scanf与printf的使用是大同小异的,scanf函数的一般形式: scanf(格式控制,地址表列)
---------需要注意的是,这里的地址表列是需要引用变量的地址。
------------如:scanf(“a = %f, b = %f, c = %f”, &a, &b, &c);
------------另外,在输入时,除了要输入变量外,还要根据scanf里面的char *format进行输入.
------------即,该scanf例子的正确输入方法是: “a = 2.3, b = 2, c = 23回车”连同a=,b=这些字符也要输入进去。
302. 有关const与define
---- #define Pi 3.1415926 // 定义符号常量
---- const float pi = 3.1415926; // 定义常变量
3021. 常变量与常量的异同是:常变量具有变量的基本属性:有类型,占存储单元,只是不允许改变其值。
---------可以说,常变量是有名字的不变量,而常量是没有名字的不变量。
3022. 定义符号常量用#define指令,它是预编译指令,它只是用与常量代表一个字符串,在预编译的时候仅是进行字符替换,即,在预编译后,符号常量就不存在了(全部都置换成3.1415926了),对符号常量的名字是不分配存储单元的。
3023. 而,常变量要占用存储单元,有变量值,只是该值不改变而己。
3024.总的来说:
---- #define Pi 3.1415926 // 定义符号常量,不占内存单元,编译后就将原程序中所有Pi转换成数字
---- const float pi = 3.1415926; // 定义常变量,占内存单元,相当于一个不变值的变量
3025.#define和用const定义还有一个区别是,用const定义的可以指定类型,而#define定义的常量是不分类型的。
// c0305.c -- C语言第03章第05题
/**
* 题目:
* 用下面的scanf函数输入数据,使a = 3, b = 7, x = 8.5, y = 71.82, c1 = 'A', c2 = 'a'.
**/
// 该题可帮助了解怎样正确对数进行输入,熟悉使用scanf函数。
#include
int main()
{
printf("请输入数据,使a = 3, b = 7, x = 8.5, y = 71.82, c1 = 'A', c2 = 'a'\n");
int a, b;
float x, y;
char c1, c2;
scanf("a=%db=%d", &a, &b);
scanf("%f%f", &x, &y);
scanf("%c%c", &c1, &c2);
void checkprint(int, int, float, float, char, char); // 此函数非原题上,编写函数为验证结果
checkprint(a, b, x, y, c1, c2); // 函数调用
while(1);
return 0;
}
// 为了验证其输入的正确性,特意多写下列的输出函数
// checkprint函数功能,输入六个变量的值。
void checkprint(int a, int b, float x, float y, char c1, char c2)
{
// 输出刚刚输入的结果。
printf("\n下面是输出结果:\na = %-12d, b= %-12d", a, b);
printf("\nx = %-12.1f, y = %-12.2e", x, y);
printf ("\nc1 = %-12c, c2 = %-12c\n", c1, c2);
// 检查其正确性并提示信息
// if(3 == a && 7 == b && 8.5 == x && 71.82 == y && 'A' == c1 && 'a' == c2)
// 在判断浮点型数据时,不能直接这样等于,判断两者之差,一般在 1e-6范围内认为相等。
if(3 == a && 7 == b && (x-8.5<1e-6) && (y-71.82<1e-6) && 'A' == c1 && 'a' == c2)
{
printf("\n输出结果正确,与题目相符合!\n");
}
else
printf("\n输出结果错误,请检查输入的方式。\n");
return;
}
// 本程序使用 Microsoft Visual C++ 6.0 验证正常。
// 第一次尝试输入时:
/************************************************
请输入数据,使a = 3, b = 7, x = 8.5, y = 71.82, c1 = 'A', c2 = 'a'
a=3b=7
8.5
71.82Aa // <-这里在输入71.82前,输入了回车,出错
下面是输出结果:
a = 3 , b= 7
x = 8.500000 , y = 7.182000e+001
c1 = A , c2 = a
输出结果错误,请检查输入的方式。 // <-这里出错了
Press any key to continue
************************************************/
// 修改过程:
/**
原:if(3 == a && 7 == b && 8.5 == x && 71.82 == y && 'A' == c1 && 'a' == c2)
因: 在判断浮点型数据时,不能直接这样等于,判断两者之差,一般在 1e-6范围内认为相等。
改: if(3 == a && 7 == b && (x-8.5<1e-6) && (y-71.82<1e-6) && 'A' == c1 && 'a' == c2)
*/
// 修改后输入:
/************************************************
请输入数据,使a = 3, b = 7, x = 8.5, y = 71.82, c1 = 'A', c2 = 'a'
a=3b=7
8.5 71.82Aa
下面是输出结果:
a = 3 , b= 7
x = 8.5 , y = 7.18e+001
c1 = A , c2 = a
输出结果正确,与题目相符合!
************************************************/
// 总结:
// 从这个程序的编写调试运行过程中可以知道,
// 在scanf函数中,需严格按照格式控制进行输入。
// 在float比较时,注意不要直接使用==比较,而要将其设定在1e-6范围内
// c0307.c -- C语言第03章第07题
/**
* 题目:
* 设圆半径r = 1.5, 圆柱高h = 3, 求圆周长、圆面积、圆柱体积。
* 用scanf输入数据,输出计算结果,输出时要求有文字说明,取小数点后2位数字。请编程序。
**/
// 做题目的,练习C语言中printf和scanf的使用。
/**
* 做题思路:
* 这题目并不难,按照一般的思路就行了,先用一个函数输入数据,然后再分别用两个函数计算出结果。
* 整个过程,共有四个函数,一个主函数,一个用于输入数据的函数,两个用于计算的函数。
**/
#include
int main()
{
// 声明变量
float r; // 圆的半径
float h; // 圆的高
printf("-> 请根据提示输入圆的半径及高,系统将自动计算出圆的周长,面积及圆柱的体积。\n");
void valueInput(float & r, float & h); // 声明函数,在该函数中输入数值
valueInput(r, h); // 调用函数
void roundness(float r); // 声明函数,该函数实现计算并显示圆周长,圆面积的功能
void column(float r, float h); // 声明函数,该函数实现计算圆柱体积的功能
roundness(r); // 调用函数,计算圆周长及圆面积
column(r, h); // 调用函数,计算圆柱体体积
return 0;
}
// 在该函数中输入r 和 h 的数值
void valueInput(float & r, float & h)
{
printf("-> 请输入该圆的半径(输入后按回车结束):");
scanf("%f", &r);
printf("-> 请输入该圆柱的高(输入后按回车结束):");
scanf("%f", &h);
printf("\n输入完毕。。。\n");
return;
}
// 该函数实现计算并显示圆周长,圆面积的功能
void roundness(float r)
{
printf("-> 该圆的周长为:%-.2f", 3.14 * r * 2);
printf("\n-> 该圆的面积为:%-.2f", 3.14 * r * r);
return;
}
// 该函数实现计算圆柱体积的功能
void column(float r, float h)
{
printf("\n-> 该圆柱的体积为:%-.2f", 2 * 3.14 * h * r);
printf("\n");
return;
}
// 运行测试
/** ** ** ** ** ** ** ** ** ** ** ** ** ** **
-> 请根据提示输入圆的半径及高,系统将自动计算出圆的周长,面积及圆柱的体积。
-> 请输入该圆的半径(输入后按回车结束):34.23
-> 请输入该圆柱的高(输入后按回车结束):34.2
输入完毕。。。
-> 该圆的周长为:214.96
-> 该圆的面积为:3679.12
-> 该圆柱的体积为:7351.78
Press any key to continue
**********************************************************/
第08章
——指针
801. 指针数组作main函数的形参
----int main(int argc, char * argv[]) argc 和 argv 是main函数的形参,是“命令行参数”。
8011. argc = argument count; // 参数个数
8012. argv = argument vector; // 参数向量
8013. main函数是操作系统调用的,实参只能由操作系统给出。命令行参数都是字符串。
8014. 命令行的一般形式: 命令名 参数1 参数2 参数3 ... 参数n
-----如: file1.exe[这个属于命令] HaHa(这个属于第一个参数) HeiHei(这个属于第二个参数)
-----这里此时, argv[0] = ”file1.exe \0” argv[1]= “HaHa\0” argv[2] = “HeiHei\0”.
-----如果使用了这个命令行参数后,再执行以下程序的话,估计就能理解这个参数的意思了。
-----void main( int argc, char * argv[])
----{ while (*argv != NULL)
---- cout << *argv ++ << endl;
----}
8015.其实,main函数中的形参不一定命名为argc和argv,可以是任意的名字,argc和argv只是习惯。
8016.总的来说,通过指针数组,可以对main传递命令行参数,使用指定的功能。
802. 动态内存分配与指向它的指针变量
8021. 内存的存储区域(稍归纳一下,其实内存里面就三个区)
-----静态存储区:是在程序编译时就已经分配好的,在整个运行期间都存在,如全局变量、常量。
-----动态存储区(栈(stack)区)函数内的局部变量就是从这分配的,但分配的内存容易有限。
-----自由存储区(堆(heap)区)也称动态分配,如new,malloc分配内存,delete,free释放内存。
8022. 建立内存的动态分配(系统提供的库函数,malloc, calloc, free, realloc)
80221. 使用malloc函数: void * malloc(unsigned int size)
--------在内存的动态存储区中分配一个长度为size的连续空间。
---------如: int * p = malloc(100); // 开辟一个100字节的空间,函数值为第1个字节的地址。
80222. 使用calloc函数:void * calloc(unsigned n, unsigned size);
--------在内存的动态存储区中分配n个长度为size的连续空间,空间大小足以存放一个数组。
---------p = calloc(50, 4); // 开辟50 * 4个字节的临时分配域,把起始地址赋给指针变量p
80223. 使用free函数: void free (void * p);
---------其作用是释放指针变量p所指向的动态空间,使这部分空间能重新被其他变量使用。free(p);
80224. 使用realloc函数:void * realloc(void * p, unsigned int size);
--------改变指针变量在动态空间所占大小,使用realloc重新分配。
--------realloc(p, 50);
---------// 将p所指向的已分配的动态空间改为50字节,分配后,p值不变,若失败,返回NULL。
第09章
——用户自己建立数据类型(类)
901.建立结构体类型
-----声明一个结构体类型的一般形式
-----struct 结构体名{成员表列};
902.定义结构体类型变量
-----假如已经声明了一个结构体类型 struct Student{};
------现在用它来定义变量。 struct Student student1, student2; // 变量student1, student2
-------还可以 struct Student{成员表列}变量名表列;
--------如:struct Student{int num} student1, student2; // 变量student1, student2
903.用typedef声明新类型名
-----命名一个新的类型名代表结构体类型:
------typedef struct{int month;}Data;
-------Data a; // 则a 的类型为 Data与原来的直接用struct定义不同的是一个少写了struct.
-----再如: typedef int Num[100]; Num a; // a 相当于 int [100]
第10章
——对文件的输入输出
1001.文件的分类
――――根据数据的组织形式,数据文件可以分为ASCII文件和二进制文件。
10011.二进制文件
------数据在内存中是以二进制形式存储的,如果不加转换地输出到外存,就是二进制文件。
------也可以认为它是存储在内存的数据映像,所以也称作映像文件(image file)。
10012.文本文件(text file)
------ASCII文件又称为文本文件。当要求在外存上以ASCII形式存储,则需要在存储前进行转换。
1002.对文件的操作及两语言操作的不同比较