1.空白和注释——提高程序的可读性
/* ......*/ 用于注释掉一段程序,但是也就是不在程序中起作用,并没有将其真正从源文件中删除。要从逻辑上删除一段c代码,更好的办法是使用#if指令。
eg:
#if 0
statements
#endif
在#if和#endif之间的程序段就可以有效地从程序段去除,即使这段代码中间已经有注释了,也无妨。
2.预处理指令
#include <stdio.h>
#include<string,h>
#define MAX_COLS 20
这3行称为预处理指令,因为它们是由预处理器解释的。预处理器读入源代码,根据预处理指令对其进行修改,然后把修改过的源代码递交给编译器。
预处理器用名叫stdio.h的库函数头文件的内容替换第一条#include指令语句,仿佛是stdio.h的内容被逐字写到源文件那个位置。
注:stdio.h头文件可以访问标准I/O库中的函数,这组函数用于执行输入和输出。stdlib.h定义了EXIT_SUCCESS和EXIT_FAILURE符号。string.h头文件提供了函数来操作字符串.
注:另一种预处理指令#define,它把MAX_COLS定义为20,当这个名字以后出现在源文件的任何地方时,它都会被替换为定义的值。这些名字一般都大写,用于提醒他们并非普通的变量。
int read_column_numbers( int columns[] ,int max);
void rearrange( char *output, char const *input, int n_colums, int const columns[]);
这些声明被称为函数原型。它们告诉编译器以后这些将在源文件中定义的函数特征。这样,当这些函数被调用时,编译器就能对它们进行准确性检查。函数 read_column_numbers返回一个整数,接受两个参数的类型分别为整型数组和整型标量的参数,函数原型中参数的名字并非必需,这里给出参数名的目的是提示它们的作用。rerrange函数接受接受4个参数,第1个和第2 个参数都是指针,指针指定一个存储于计算机内存中的值得地址。第2个和第4个参数被声明为const,这表示函数将不会修改函数调用者所传递的这两个参数。关键字void表示函数并不会返回任何值,在其他语言里,这种无返回值得函数被称为过程(procedure)。
int n_columns=read_column_numbers(columns, MAX_COLS);
在c语言中,数组参数是以引用形式进行传递的,也就是传址调用,而标量和常量则是按值传递。在函数中对标量参数的任何修改都会在函数返回时丢失。
事实上,关于C函数的参数传递规则可言表述如下:
所有传递给函数的参数都是按值传递的。
但是,当数组名作为参数是就会产生按引用传递的效果,这似乎和规则相矛盾,会在第8章做详细解释。
while( gets(input)!=NULL)
{
printf( "Original inpput :%s\n", input );
}
return EXIT_SUCCESS;
gets函数从标准输入提取一行文本并把它作为存储于作为参数传递给它的数组( input )中。一行输入由一串字符组成,以一个换行符结尾。gets函数丢弃换行符,并在改行的末尾存储一个NUL字节。
puts 函数是 gets 函数的输出版本,它把指定的字符串写到标准输出并在末尾添上一个换行符。
eg:
puts( "hello world" );
注:NUL是ASCII字符集中 '\0' 字符的名字,它的字节模式为全0。NULL值一个其值为0的指针。它们都是整型值,其值也相同,所以它们可以相互使用。
NULL在头文件stdio.h中定义。NUL不存在预定义的符号,所以如果你想使用它而不是字符常量'\0',必须自行定义。
在c程序中,字符串就是一串以NUL字节结尾电费字符,NUL虽然作为字符串终止符,但它本身不被看做字符串的一部分。字符串常量是源程序中被双引号括起来的一串字符串。eg: "Hello" 在内存中占6个字节。分别是H、e、l、l、o、NUL。
printf 函数执行格式化输出。
printf函数接受多个参数,其中第一个参数是一个字符串,描述输出的格式,剩余的参数就是需要打印的值。
常用的printf格式代码:
格式 含义
%d 以十进制形式打印一个整型值
%o 以八进制形式打印一个整型值
%x 以十六进制形式打印一个整型值
%g 打印一个浮点值
%c 打印一个字符
%s 打印一个字符串
scanf 函数——printf 函数的逆操作
scanf 函数从标准输入读取字符并根据格式字符串对它们进行转换,转换成功返回1,失败返回0。
scanf 函数接受几个参数,其中第一个参数是一个格式字符串,用于描述期望的输入类型。剩余几个参数都是变量,用于存储函数所读取的输入数据。scanf 函数的返回值是函数成功转换并存储于参数中的值得个数。
警告:
1.由于 scanf 函数的实现原理,所有标量参数的的前面必须加上一个 “&” 符号。数组参数前面不需要加上 “&” 符号(如果你在它前面加上 “&” 也没错,所以你喜欢,就可以加上去)但是,数组参数中如果出现下标引用,也就是实际参数是数组的某个特定元素,那么它前面必须加。
2.它的格式代码与printf 函数的格式代码颇为相同却又不完全相同。注意不要混淆了,下面列出了scanf 函数中常用到的格式代码,前5个格式代码用于读取标量值,所以必须加 “&” 符号。使用格式代码,除了 %c 外,输入值前的空白( 空格、制表符、换行符等 ) 会被跳过,值后面的空白表示该值的结束。因此,用 %s 格式码输入字符串,中间不能包含空白。
格式 含义|变量类型
%d 读取一个整型值|int
%ld 读取一个长整型值|long
%f 读取一个实型值(浮点数)|float
%lf 读取一个双精度实型值|double
%c 读取一个字符|char
%s 从输入中读取一个字符串|char型数组
补充说明:
putchar函数与getchar想对应,它接受一个整型参数,并在标准输出中打印该字符(字符本质上也是整数)
strcpy 函数与strncpy 函数类似,但它并没有限制需要复制的字符数量。它接受2个参数,第2个字符参数将被复制到第1个字符参数,第1个字符参数原有的字符将被覆盖。strcat 函数也接受2个参数,但它把第二个字符串添加到第一个字符串的末尾。
再字符串内进行搜索的函数式strchr,它接受2个 参数,第1个参数是字符串,第2个参数是一个字符。这个函数在字符串内搜索第二个字符第1次出现的位置,如果成功就返回指向这个位置的指针,失败就返回NULL指针。
strstr 函数接受2个参数。两个参数都是字符串。作用是搜索第2个字符串在第1个字符串中第一次出现的位置。
printf 和 scanf 用于执行格式化的输出和输入
getchar 和 putchar用于执行非格式化的输入和输出。