《C程序设计语言》学习笔记(01)起步

C程序设计语言 第2版

《The C Programming Language》

封面如下,选取书中知识点用以记录学习。


第1章 导言

 
1.1 入门

  • 源程序 test.c;
  • 编译 test.obj
  • 连接 test.exe

C语言程序中,

  • 函数:包含语句,指定要执行的计算操作。
  • 变量:存储计算过程中使用的值。

每个程序都以 main 函数的起点开始执行。

构成 C 程序的基本单位是函数。

 
1.2 变量与算术表达式

所有变量都必须声明后使用。

声明 declaration:说明每个标识符的含义,不需要预留存储空间。

定义 definition:预留存储空间的声明,创建变量或分配存储单元。

舍位:整数除法,结果中任何小数位都会被舍弃。 5/9 = 0

华氏、摄氏对照公式:℃ = (5/9) (℉-32)

#include <stdio.h>

// 当 fahr= 0,20, ... ,300 时,打印华氏温度与摄氏温度对照表
int main()
{
    float fahr, celsius;
    int lower, upper, step;

    lower = 0; // 温度表的下限
    upper = 300; // 温度表的上限
    step = 20; // 步长

    fahr = lower;
    printf("Fahr Celsius\n");
    while(fahr <= upper)
    {
        celsius = (5.0/9.0)*(fahr-32);
        printf("%3.0f\t%6.1f\n", fahr, celsius);
        fahr = fahr + step;
    }
    return 0;
}

%6.2f:按浮点打印,至少6个字符宽,小数点后两位小数。

1.3 for语句

判别式为真,则执行循环体。

适合初始化和增长步长都是单条语句并且逻辑相关的情形。

#include <stdio.h>
// 当 fahr= 0,20, ... ,300 时,打印华氏温度与摄氏温度对照表
int main()
{
    float fahr;
    printf("Fahr Celsius\n");
    for(fahr=0; fahr <= 300; fahr = fahr+20)
        printf("%3.0f %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
    return 0;
}

 
1.4 符号常量

define LOWER 0 //末尾没有分号!

 

1.5 字符输入输出

c = getchar();//从文本流中读入下一个输入字符
putchar(c);//打印一个字符

1.5.1 文件复制

#include <stdio.h>
// 版本2:按字符将输入复制到输出
int main()
{
    int c;
    while((c = getchar())!= EOF)	//end of file,文件结束符
        putchar(c);
    return 0;
}

这里将 c 声明成 int ,因为 c 必须足够大,除了存储字符,还要存储 EOF。(EOF在<stdio.h>中是整型)

1.5.2 字符计数

for(nc=0; getchar() != EOF; ++nc);	//空语句

1.5.3 行计数

while((c=getchar() != EOF))
    if(c=='\n')
        ++nl;

1.5.4 单词计数(不包括空格、制表符或换行符的字符序列)

#include <stdio.h>

#define IN 1
#define OUT 0

// 版本1:利用state标志位
int main()
{
    int c, nl, nw, nc, state;
    state = OUT;	//state不在单词中
    nl = nw = nc = 0;	//line, word, char
    while((c = getchar())!= EOF)
    {
        ++nc; // 字符+1
        if(c == '\n')
            ++nl; // 行数+1
        if(c == ' ' || c == '\n' || c == '\t')
            state = OUT;	//单词外
        else if(state == OUT)	//非空格且单词外
        {
            state = IN;		//改单词内
            ++nw;			//单词+1
        }
    }
    printf("nl=%d, nw=%d, nc=%d\n", nl, nw, nc);23
    return 0;
}

// 版本2:利用上一个字符跟本字符一起比较
int main()
{
    int c, nw=0, lastc = ' ';
    while((c = getchar())!=EOF)
    {
        if(lastc == ' ' && c != ' ')
            nw++;
        lastc = c;
    }
    printf("单词数: %d\n", nw);
    return 0;
}

1.6 数组

/* 统计各个数字、空白符及其他字符个数*/
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=='\t' || c=='\n')
        ++nwhite;
	else
        ++nother;

 

1.7 函数

同一函数不能分割存放在多个文件中。

形参:函数定义中圆括号内列表中出现的变量。

实参:函数调用中与形参对应的值。

函数不一定都有返回值,而main末尾有 return,可以向其调用者(程序的执行环境)返回一个值。

  • 返回值为0,正常终止;
  • 非零,出现异常情况或出错结束条件。

函数原型(声明):int power(int m, int n); 它必须与 power 函数的定义和用法一致。

函数原型与函数声明中参数名不要求相同,也可写成:int power(int, int);
 

1.8 参数——传值调用

  1. 值传递:传递给被调函数的参数值存放在临时变量(本地副本)中,而不是存放在原来的变量中。

    被调函数不能直接修改主调函数中变量的值,只能修改其私有的临时副本的值。

  2. 指针:指向变量的地址。

    调用者向被调函数提供待设置值的地址,可以让函数修改主调函数中的变量

  3. 数组参数:数组名作为参数时,传递给函数的值是数组起始元素的位置或地址 —— 并不复制数组本身。
     

1.9 字符数组

当C语言程序中出现类似hello\n的字符常量时,将以字符数组的形式存储。数组的各元素分别存储字符串的各个字符,并以\0标志字符串的结束。

/* 程序读入一组文本行,并把最长的文本行打印出来 */
#include <stdio.h>
#define MAXLINE 1000 //允许的输入行最长长度

int getLine(char line[], int maxline); // 将一行读入line,返回长度
void copy(char to[], char from[]); // from复制到to

int main()
{
    int len; // 当前行长度
    int max; // 目前为止最长行的长度
    char line[MAXLINE];
    char longest[MAXLINE];

    max = 0;
    while((len = getLine(line, MAXLINE)) > 0) //行不为空,则拿下
    {
        if(len > max) //拿到最长行给longest
        {
            max = len;
            copy(longest, line);
        }
    }
    if(max > 0)
        printf("%s", longest); //最后输出最长行。这里longest是自带换行符的
    return 0;
}

int getLine(char line[], int maxline)
{
    int c, i;
    // 不超过行最长长度,不到EOF,不到换行符,要同时成立
    for(i=0; i<maxline-1 && (c=getchar())!=EOF && c!='\n'; ++i)
    {
        line[i] = c;
    }
    if(c == '\n') //如果是因为\n 而结束,说明是一行,\n 加到字符串末尾
    {
        line[i] = c;
        ++i;
    }
    line[i] = '\0'; //字符串结尾
    return i;
}

void copy(char to[], char from[])
{
    int i = 0;
    while((to[i] = from[i]) != '\0')
        ++i;
}

1.10 外部变量与作用域

局部变量、自动变量 auto、私有变量 保存在栈中

  1. 只在函数被调用时分配存储单元,执行完毕退出时消失。
  2. 在函数的两次调用之间,自动变量不保留前次调用时的赋值。
  3. 每次进入函数时都要显示为其赋值。
  4. 如果没有赋值则其中存放的是无效值。

外部变量 extern

  1. 所有函数都可通过变量名来访问,因此可以用来在函数间交换数据而不使用参数表。
  2. 程序执行期间一直存在,即使再对外部变量赋值的函数返回后,这些变量仍保持原来的值不变
  3. 定义在所有函数之外,且只能定义一次,定义后编译程序将为它分配存储单元。
  4. 在使用外部变量的函数中,必须声明相应的外部变量。
extern int max;
1.若外部变量定义在使用它的函数之前,可以省略extern声明;
2.若变量在 file1 中定义,在 file2 和 file3 中使用,那么 file2 和 file3 必须声明来建立该变量与其定义之间的联系。
3.通常把变量和函数的 extern 声明放在一个单独的文件中 → 头文件

静态变量 static

  1. 限定的外部变量和函数,其后的对象的作用域限定为被编译源文件的剩余部分,可以达到隐藏外部对象的目的。
  2. 声明内部变量,只能在特定函数中使用,但一直占据存储空间的变量。赋值一次,多次函数调用之间保持值不变。
  3. 静态变量只在第一次进入程序块时被初始化一次。

寄存器变量 register

  1. 告诉编译器,变量在程序中使用频率较高。
  2. 思想:变量放机器寄存器中,使程序更小、执行速度更快,编译器直接忽略。
  3. 只适用于 auto 变量和函数的形参。
  4. 寄存器变量的地址不可访问。(没有内存位置,不能用 &)
     

 
C语言编译后,将内存分为以下几个区域:

  1. 栈(stack):由编译器进行管理,自动分配和释放,存放函数调用过程中各种参数、局部变量、返回值以及返回地址。

  2. 堆(heap):用于程序动态申请分配和释放空间。(malloc, free)

    正常情况下,申请的控件在使用结束后应该释放,若程序员未释放,则程序结束时系统自动回收。(不是数据结构中的“堆”)

  3. 全局(静态)存储区:分为 DATA 段和 BSS 段

    DATA 段(全局初始化区),存放初始化的全局变量和静态变量;

    BSS 段(全局未初始化区),存放未初始化的全局变量和静态变量。

  4. 文字常量区:存放常量字符串,程序结束后由系统释放。

  5. 程序代码区:存放程序的二进制代码。


附录

电子书链接:https://pan.baidu.com/s/1xNX9Exu_2msDeTtWgRbiwQ
提取码:irsd

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值