<<深入浅出>>嗨翻C语言观后感1

主要记录我在《嗨翻C语言》中记录的知识点,以备用时参考。

C语言入门

  1. gcc(GNU编译器套件--GNU Compiler Collection)是个C编译器。
   Linux         直接存在
   Mac           可使用Xcode
   Windows       可用Cygwin(模拟Unix环境)或MinGw(仅运行程序)
  1. 计算机仅理解机器代码-->二进制流。
  2. int main()函数是程序中所有代码的起点。
  3. 若要检查程序的退出状态(通常是int main()函数的返回值):
  Windows下可在命令行输入         echo %ErrorLevel%
  Linux或Mac下输入               echo $?

Note:Cygwin中输入 echo $?

  1. 一条命令解决编译和运行,利用&&即可,eg:
  gcc test.c -o test **&&** ./test
  1. 在类Unix(Linux/Mac)操作系统中,运行程序必须指定程序所在目录,除非该目录位于PATH环境变量中。
  2. C语言中,0为假,其他情况均为真
  3. & |&& ||的异同:
  同:都携带两个条件
  异:&&和||,在特定条件下可以跳过第二个条件。
      &和|必须且总是计算两个条件;而且可以对数字的某一位进行布尔运算。

example1: A && B,若A为假,则B不必被计算;A & B,无论A真或假,B都必须被计算;
example2: A || B,若A为真,则B不必被计算;A | B,无论A真或假,B都必须被计算。

  1. 部分函数、关键字、语句举例:
  • puts() 在命令提示符或终端显示字符串。
  • scanf() 从标准输入读取数据;可输入多个字段;可输入结构化数据
int x;
scanf("%d", &x);//fscanf(stdin, "%d", &x)

它在读取数据时,遇到空格就停止,除非多个格式化占位符,eg:

#include <stdio.h>

int main()
{
    char msg[21];
    char phone[12];
    scanf("%20s %11s", msg, phone);
    printf("输出\n");
    printf("%s---------%s\n", msg, phone);
    printf("%li  %li\n", sizeof (msg), sizeof (phone));
    msg[2] = '\0';
    phone[7] = '\0';
    printf("%s---------%s\n", msg, phone);
    return 0;
}

运行结果如下:

Liana 19996999999
输出
Liana---------19996999999
21  12
Li---------1999699

*example1 ---- scanf()获取数: *

int num = -1;
scanf("%i", &num);  /*scanf()需要的是变量地址*/

*example2 ---- scanf()获取字符数组: *

char ex[11];
scanf("%10s", ex); 
 / *ex字符数组设置大小为11,但scanf获取的长度至多为10,
   *因为C语言中存在着标志字符串结束的空字符'\0',
   *与fgets()函数获取字符数组内容时有区别。* /
  • fgets(变量, sizeof(变量), stdin)eg:
#include <stdio.h>

int main()
{
    char msg[10];
    fgets(msg, 10, stdin);
    //char *msg = malloc(sizeof(char)*10);
    //fgets(msg, 10, stdin);
    printf("输出\n");
    printf("%s---------", msg);
    printf("%li\n", sizeof (msg));
    return 0;
}

运行结果如下:

Liana
输出
Liana
---------10
  • printf() 显示格式化输出;把数据发送到标准输出。
printf("i like cakes.\n")
//fprintf(stdout, "i like cakes.\n");

Note: <stdio.h> 包含能在终端读写数据的接口。

  • continue 可以跳过循环体其余部分,回到循环开始(即永远跳至循环条件处)。
    example1 ---- while循环体:
/ *先判断条件,条件满足则再执行语句块
  *重复上述步骤 * /
    int i = 0;
    while(i < 8)
    {
        printf("%d  ", i);
        if(i == 2)
        {
            i += 2;
            continue;
        }
        ++i;
    }

这段代码输出结果如下:

0  1  2  4  5  6  7

example2 ---- do-while循环体:

/* Loop:先执行一次语句块判断条件,再判断条件是否,满足则重复上述步骤 */
    int i = 0;
    do {
        ++i;
        printf("%d  ", i);
        if( i == 3)
        {
            i += 2;
            continue;
        }
    } while(i < 7);

这段代码输出结果如下:

1  2  3  6  7
  • break 可以跳出循环语句块和switch语句块,但不能从if语句块中跳出。

存储器和指针(含字符串)

  1. 总线错误:程序不能更新那一块存储空间。
    段错误abort trap <-- 缓冲区溢出
  2. C语言中,用双引号定义的字符串叫做字符串字面值string literal),是常量;而字符数组不是。
    example :
  char a[] = "hello";
  1. 指针可以避免副本、共享数据
    指针只是一个保存存储器地址的变量,是进程存储器中真实编号的地址
    *可以读取(作为右值)或设置存储器地址的内容(作为左值)。
  2. 赋值语句也有返回值。
    example 1 ---- 赋值:
  int x, y;
  y = (x = 4) /*等价于 y = x = 4;*/
  //此时y的值为4

example 2 ---- 判等:

  int x = 2;
  int y = (x == 2);
  //此时y的值为1
  1. 引用
  int x = 4;
  int *a = &x;//a指向变量x的地址
  int k = *a;//*a作为右值,可以读出a上存储的地址(x的地址)中存储的值(x的值)
  //k = 4
  1. sizeof()是运算符,而非函数。
    程序在编译时期将sizeof编译为一串指令,确定存储空间的大小,从而计算sizeof()的值。
    它在计算字符串字面值长度时会包含空字符\0的长度,eg :
    int k = sizeof ("haha");
    printf("%d", k);

此处结果为:

5
  1. 数组变量也是个地址,eg :
    int x = 3;
    int a[2] = {3, 4};
    printf("%p , %p\n", &x, a);
    //%p  可用于格式化地址(十六进制)

此处会打印两个十六进制地址值,eg:

0x7ffe11d245dc , 0x7ffe11d245e0
  1. 计算机会为每个进程分配一个简版存储器(存储器是进程的) 。
    函数中声明的变量通常保存于栈中,在main()函数外部声明的变量保存于全局变量中。
    栈区 <-存局部变量
    堆区 <-存全局变量
    全局区
    常量段(只读存储器) <-存字符串常量
    代码段
  2. 将指针强制转化为一般数字,eg :
    int x = 4;
    int  *p = &x;
    long a = (long) p;
  1. 修改const修饰的变量,编译期会报错。
  2. 关于数组的相关计数,
    位置------------------从1开始
    索引、下标-------------从0 开始
  3. 数组可以当指针用,
    将数组传递给函数时,函数会将其作为指针变量。
    把数组变量传给指针,会发生退化(长度将未知),
    example1:
#include <stdio.h>

void fun(char msg[])//实际为指针变量
{
    printf("%s\n", msg);
    printf("%li", sizeof (msg));//这里计算的大小是指针变量的大小,而非字符串的大小。
}

int main()
{
    char *s="i am a cute, smart girl.";
    fun(s);
    printf("\n");
    char ss[] ="i am a cute, smart girl.";
    fun(ss);
    return 0;
}

该程序运行结果如下:

i am a cute, smart girl.
8
i am a cute, smart girl.
8

example2:

#include <stdio.h>

int main()
{
    char *s1="i am a cute, smart girl.";
    char ss1[] ="i am a cute, smart girl.";
    printf("%s\n", s1);
    printf("%li\n", sizeof (s1));
    printf("%s\n", ss1);
    printf("%li", sizeof (ss1));
    return 0;
}

该程序运行结果如下:

i am a cute, smart girl.
8
i am a cute, smart girl.
25

创建小工具

  1. sed 流编辑器(stream editor) ---- 搜索、替换文本
  2. 标准输入/输出/错误


    标准输入/输出/错误.png
  3. 重定向
  • 默认情况下,标准输出会发送到显示器。可以借助>将标准输出重定向到文件。
  • 默认情况下, 标注输入来从键盘读取数据。可以借助<将标准输出重定向到文件。
  • 标准错误用于输出错误消息。可以借助2>重定向标准错误。
    Note:重定向最多可以写两个文件, 一个标准输出,一个标准错误。
    要同时输出多个文件,则需要创建自己的数据流,例如fopen()。
    eg:
#include <stdio.h>

int main()
{
    char word[10];
    int i = 0;
    while(scanf("%9s", word) == 1)
    {
        ++i;
        if(i % 2)
            fprintf(stdout, "%s\n", word);
        else
            fprintf(stderr, "%s\n", word);
    }
    return 0;
}
//secret.txt的内容如下:
//THE I GIRL'S AM NAME VERY IS CUTE LIANA.

在该程序中,将标准输入重定向到文件secret.txt,并将标准输出、标准错误分别重定向到message.txt和message2.txt中:

gcc main.c -o test
./test < secret.txt > message.txt 2> message2.txt

运行结果如下:

//message.txt 的内容
THE
GIRL'S
NAME
IS
LIANA.
//message2.txt 的内容
I
AM
VERY
CUTE

4.管道pipe | 能连接一个进程的标准输入与另一个进程的标准输出
A | B 系统同时运行A和B两个程序,并将A的输出变成B的输入
流水线一连串相连的进程
当管道连接多个进程时, < 会把文件内容发送到流水线中第一个进程的标准输入, > 会捕获流水线中最后一个进程的标准输出。

  1. 创建数据流/C语言中文件的使用
    FILE *file = fopen(文件路径, 模式);//打开数据流
    fclose(file);//关闭数据流
    一个进程能拥有的数据流是有限的,所以用完应及时关闭。
模式
w(写文件,write)  r(读文件,read) a(在文件末尾追加,append)
FILE *infile = fopen("input.txt", "r");
FILE *outfile = fopen("output.txt", "w");
fprintf(outfile, "你很%s", "好看");
char sentence[20];
fscanf(infile, "%19s", sentence);
fclose(infile);
fclose(outfile);
  1. 命令行小工具
ps -ae//显示所有进程,包括后台运行的进程
tail -t 文件名//持续显示文件末尾新添加的数据
  1. 修改程序工作方式
  • 对于GUI程序:修改程序首选项
  • 对于命令行程序:传递命令行参数
    • main函数的两种形式
      • int main()
      • int main(int argc, char *argv[])其中argv[0]为待运行程序的名字,argc记录的是数组中元素的个数
        Note:在处理上述函数的参数时,可以由库代劳,使用时需要包含#include <unistd.h>。
        getopt()每次调用都会返回命令行中下一个参数,optarg变量指向选项后的那个参数,optind保存该函数从命令行读取了几个选项。
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    char *delivery = "";
    int thick = 0;
    int ch;

    while ((ch = getopt(argc, argv, "d:t")) != EOF/*-1*/)
    {
        switch (ch)
        {
        case 'd':
            delivery = optarg;
            break;
        case 't':
            thick = 1;
            break;
        default:
            fprintf(stderr, "Unknown option: '%s'\n", optarg);
            return 1;
        }
    }
    argc -= optind;
    argv += optind;

    if(thick) puts("Thick crust.");
    if(delivery[0]) printf("To be delivered %s. \n", delivery);

    puts("Ingredients: ");
    for (int count = 0; count != argc; ++count)
        puts(argv[count]);
    return 0;
}

该程序结果如下:

gcc main.c -o order_pizza
./order_pizza Anchovies
      Ingredients: 
      Anchovies
./order_pizza Anchovies Pineapple
      Ingredients: 
      Anchovies
      Pineapple
./order_pizza -d now Anchovies Pineapple
      To be delivered now. 
      Ingredients: 
      Anchovies
      Pineapple
./order_pizza -d now -t Anchovies Pineapple
      Thick crust.
      To be delivered now. 
      Ingredients: 
      Anchovies
      Pineapple
./order_pizza -d
      ./order_pizza: option requires an argument -- 'd'
      Unknown option: '(null)'
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,701评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,649评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,037评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,994评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,018评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,796评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,481评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,370评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,868评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,014评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,153评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,832评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,494评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,039评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,437评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,131评论 2 356

推荐阅读更多精彩内容

  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,746评论 0 10
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,392评论 0 5
  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,446评论 3 44
  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,345评论 0 2
  • 学习C语言程序设计都会用到高等数学知识和计算机基础理论知识。 使用可变参数应该有以下步骤: 1)首先在函数里定义一...
    皓小天阅读 5,786评论 0 2