《The C Programming Language, 2nd Edition》K&R Chapter 1 - A Tutorial Introduction 笔记
printf
printf("\c");
MinGW gcc输出c
。(\c不是转义序列)
printf("%6d", -17);
,输出□□□-17
,其中□表示空格。(%6d中6表示最少打印宽度,6是正数表示右对齐,如果是负数则表示左对齐)
printf("%.0f", -17.8);
,输出-18
。(%.0f中.0表示小数精度)
%o表示8进制,%x表示16进制,%%表示%。
变量类型
int通常为16位或32位,16位取值范围为-32768 ~ +32767。
long至少为32位,通常为32位。
float通常为32位,至少6位有效数字,取值范围。
常量
文件结束符EOF,在<stdio.h>中定义,int类型,值在char的取值范围之外。
'A'是字符常量,本质是整数,值取决于编译器认为的源文件字符集。在ASCII中,'A'为65,'\n'为10。在任何字符集中'0'、'1'、'2'、...、'9'都是连续递增的。
运算符
如果算术运算符所有操作数都为整型,则执行整型运算(如舍位除法)。其中一个操作数为浮点,则执行浮点运算。
nl = nw = nc = 0;
的执行顺序为nl = (nw = (nc = 0));
。
||和&&是短路运算符。
定义与声明
定义包含声明,定义会分配内存,而声明不会。
ANSI C之前,函数原型声明包含返回值类型,不包含形参列表,如int power();
。
函数在调用之前必须存在函数原型声明。
因此,ANSI C之前,如果一个函数,缺省函数原型声,编译器认为这个函数隐式声明返回值类型为int。
ANSI C兼容旧式函数原型声明。
ANSI C支持函数原型声明包含形参列表,其中形参名是可选的。如int power(int, int);
。
当函数原型声明中包含形参列表时,编译器会检查实参列表,并进行适当的强转。不包含时,编译器不检查实参列表,整数强转为int,浮点强转为double。
在函数原型声明中,不包含形参列表与形参列表为void的含义不同,前者表示编译器不检查实参列表,后者表示编译器检查实参列表,如果实参存在,则报错。
ANSI C之前,函数定义的语法与ANSI C差异较大。ANSI C兼容旧式函数定义。
在函数外部定义的变量称为外部变量。
外部变量定义后,外部变量是静态的(在程序运行期间一直存在)。
在外部变量定义之前访问它,必须使用extern显式声明。在定义之后访问它,可选使用extern显式声明。
访问在其他文件中定义的外部变量(前提是外部链接),必须使用extern显式声明。
函数
return;
不返回有用的值,而不是不返回值。例如:
#include <stdio.h>
int func()
{
return;
}
main()
{
printf("%d", func());
}
MinGW gcc输出1
。
函数的参数是值传递的,保存在临时变量形参中,修改形参的值不影响实参的值。
在函数调用期间存在,函数退出时销毁的局部变量称为自动变量。
auto变量是自动变量,static变量是静态变量,反之不成立。
例程
复制文件
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
}
统计字符数
#include <stdio.h>
main()
{
double nc;
for (nc = 0; getchar() != EOF; ++nc)
;
printf("%.0f\n", nc);
}
统计行数
#include <stdio.h>
main()
{
int c, nl;
nl = 1;
while ((c = getchar()) != EOF)
if (c == '\n')
++nl;
printf("%d\n", nl);
}
统计单词数(假设不包含空格、制表符、换行符的字符序列为单词)
- 起始state为OUT。
- 当遇到非空格、制表符、换行符字符时,state置IN,单词数自增。
- 当遇到空格、制表符、换行符时,state置OUT。
#include <stdio.h>
#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */
main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF) {
++nc;
if (c == '\n')
++nl;
if (c == ' ' || c == '\n' || c = '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf("%d %d %d\n", nl, nw, nc);
}
统计各个数字、空白符及其他字符出现的次数
#include <stdio.h>
/* count digits, white space, others */
main()
{
int c, i, nwhite, nother;
int ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit[i] = 0;
while ((c = getchar()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c-'0'];
else if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
else
++nother;
printf("digits =");
for (i = 0; i < 10; ++i)
printf(" %d", ndigit[i]);
printf(", white space = %d, other = %d\n",
nwhite, nother);
}
幂函数
#include <stdio.h>
int power(int m, int n);
/* test power function */
main()
{
int i;
for (i = 0; i < 10; ++i)
printf("%d %d %d\n", i, power(2,i), power(-3,i));
return 0;
}
/* power: raise base to n-th power; n >= 0 */
int power(int base, int n)
{
int i, p;
p = 1;
for (i = 1; i <= n; ++i)
p = p * base;
return p;
}
打印最长的行
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/* print the longest input line */
main()
{
int len; /* current line length */
int max; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) /* there was a line */
printf("%s", longest);
return 0;
}
/* getline: read a line into s, return length */
int getline(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
/* copy: copy 'from' into 'to'; assume to is big enough */
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}