【C语言】入门认识

本文篇幅略长,我们的目标是大体了解C语言的基础知识,每个知识点都为最基本的通俗认识,之后会细讲。如有错误或理解不到位,还望各佬们大力批评斧正(右下角有目录可供查询)。若有帮助麻烦点个关注吧

C语言是什么

C语言与其他语言的对比

既然选择学习C语言,那我们要知道C语言是什么,相较于其他热门语言有何优势(java/cpp/pytho),由此目的我们先来简单了解一下为何学习C语言

c语言诞生于1972年,是一个通用型命令式计算机编程语言,广泛用于底层开发,其支持结构化编程,词汇变量范围与递归,同时也是一种能够预防各类未预期操作的静态类型系统,最初的目标在于构建编写系统软件。

c++诞生于1983年,相较于C语言,c++紧随c语言的步伐,c++是C语言的超集,大家所知道的C语言是面向过程的。

Java语言诞生于1995年5月23日,并在1996年1月,第一个JDK-JDK1.0诞生,开启了一新编程语言的伟大逆袭之旅。java是面向对象的,那么C语言为了面向对象,所以诞生出现在大家所熟知的c++,被广泛视为大规模应用构建软件

python诞生于1989年的一个圣诞节,其创作者Guido van Rossum,Python第一个优势在于语法优雅简单,Python写起来就像写英文一样,可读性非常高,清晰易懂。比较容易理解。第二个优势是编程范式,它支持很多编程范式,面向过程、面向对象,它还支持函数式编程。

总的来说,C语言是一门基础语言,学好C语言更方便我们理解其他语言,做到C生万物

什么是面向对象,什么是面向过程

ok,大家看到这,不免会产生疑问,什么是面向对象?什么是面向过程?本作者给出以下通俗的解释

以平时大家在家中用洗衣机洗衣服为例子,彦祖们难免会产生以下几个动作:1.先将衣服一起放入洗衣机2.倒入洗衣服3.设置洗衣机工作模式,定时等系列操作4.启动洗衣机5.完成洗衣并甩干。当然更高端的洗衣机也会有更复杂的操作,而这些细枝末节的过程,彦祖们可以类比成我们语言中的面向过程

而我们的面向对象处理洗衣服的话,我们就可以抽象出几个工作需要的对象,如以洗衣服为例,我们就产生对象:彦祖们 衣服 洗衣机这3个对象。面向对象处理就不需要关心洗衣的过程,洗衣机是如何运作等等,我们只需要关心对象,而对象之间的交互我们就可以不用关心了

注意:面向对象和面向过程并没有好坏之分,以实际情况为重

什么是上层,什么是底层

这时候看了c语言中的对于广泛底层开发,你会问什么是上层什么是底层

如此图来看,我们电脑一般大致分为 硬件,操作系统,应用。而驱动层是操作系统通过驱动来控制硬件工作的,我们的操作系统及以下为底层,应用及以上为上层

如果有兴趣的话点我了解更多上层与底层

如何写一个C语言程序

相信哥,保姆级教学你驾驭不住

Hello World

俗话说的好,工欲善其事,必先利其器。我们想要写出C语言就要下载可以运行C语言的编辑器,我们以vs2022为例。

  • 1.我们先点击创建新项目

2.依次点击空项目,并点击下一步

3.跳转到这一个界面时候,注意你的项目名称 最好写成英文的以免存放时发生乱码

4.点源文件-->添加-->新建

5.依次点击,这时候彦祖们会问了为什么是cpp后缀啊,因为vs里c和c++并不分家,值得注意的是你名称里要写上英文.c后缀

  • 走到这一步我们就可以开始写代码了 其基本格式为

  • 按ctrl+ F5或者ctrl+ fn+ F5运行我们的代码

C语言的基本格式

可能开始你并不知道这些都是什意思,你可以理解为这是写c语言的基本框架。接下来会一一解释

  • int main()与return 0;

我们先从程序第二行看起,你要知道main()是整个c语言程序的入口,即从此开始编译,{}这个的意思是你需要写的代码块就放在这里面, 而main前面的int为返回类型,现在不必深究下面会有解释,那么第6行的return 0;呢,顾名思义,return即返回的意思,看到这里你就想到了int(返回类型),是的!返回类型与返回值联动,return 0即返回一个0值。

  • printf(“Hello World”);与#include <stdio.h>

这里printf是你C编译系统提供的函数库中的输出语句,何为输出?即在你的屏幕上打印出内容,而后面的hello world为你输出内容,那么上面的#include <stdio.h>,在我们使用函数库里的输入输出函数时,编译器要求程序提供有关函数的信息,而#include <stdio.h>就是起提供信息的作用。通俗理解就是,若想用c语言函数库的东西(printf 等等)就要 先给人家打招呼,招呼都不打就直接拿来使用失败是必然的·。

  • #include

通俗理解为用此指令把后面所跟的信息调用,为编译预处理指令。

  • <stdio.h>

stdio.h是系统提供的一个文件名,stdio是standard input &output的缩写,顾名思义应该就可以知道为什么在调用printf语句时要加上这一句了吧。

注意:各位彦祖们在写代码的时候要使用英文输入法去写,vs是很严格的编译器
每一个语句后面要加入分号(;)表示这一行或者语句结束。养好良好的编译习惯从你我做起

一个基础的良好的习惯

  1. 学会写注释

注释的作用是给代码做说明,方便别人阅读和理解代码,写注释是很好的编程习惯。编译器会直接忽略代码中的注释,注释不对程序功能产生任何影响,即使不写注释,也不影响程序代码。

三种注释写法:

1.单行注释,/* */之间的所有内容会被作为注释。

/* 这是注释 */

2.多行注释,/* */之间的多行内容会被作为注释。

/*
注释1
注释2
*/

3.单行注释

//这是一个注释

  1. 变量的命名

注意:你变量的命名最好要有一定的意义,不要abcd命到底,前期看不出什么弊端,到时候要写代码变多后连自己都不知道这个变量是什么意思了。

  1. 创建变量

各位大佬们创建变量的时候最好先给它赋一个0值,到最后再去赋予其他值不要直接这样创建

int num;

当然了彦祖们会疑惑这样创建有什么问题,接下来我们来一个报错解释

所以我们最后在初始化的时候先给赋予一个0值,到以后再赋予其他值,变量变量即以后可以被改变。不仅可以美化代码,也会降低报错的可能

int num=0;

变量的类型与大小

C语言中为什么需要变量类型?以你买菜为例,超市里的价格有零有整,买洋酒以英文开头等等实例证明C语言需要变量类型

有了各变量类型后,我们要知道各个变量类型所占的空间大小,这个时候我们需要我们的sizeof函数来计算,单位是字节

这个时候就要问了,什么是字节?我直接上图理解

bite--比特位,最小的计算机储存单位
byte--字节
kb
mb
gb
tb
pb
换算单位是8bite=1byte,其余的往下都是1024的换算

细心的朋友看见了,为什么我的long与int都是占4个字节

因为按照C语言规定sizeof(long)只需>=sizeof(int)即可

在C语言中,对于整型默认是int型,对于小数默认是double类型,编译器可以自动向上转型,如int转long,而double转float就不能自动转了,故在写float时后面值加f

而double就不用加了,默认小数是double类型

  • 对于scanf的提议,

  • 若想scanf不报错就需要在代码第一行添加

#define _CRT_SECURE_NO_WARNINGS 1

  • 若想一劳永逸,就需要在newc++file.cpp里添加上面代码

作用域与生命周期

作用域(scope)

是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用

的而限定这个名字的可用性的代码范围就是这个名字的作用域。

1. 局部变量的作用域是变量所在的局部范围。

2. 全局变量的作用域是整个工程。

通俗来说你的变量在哪你的此变量的作用域就在哪

生命周期

1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。

2. 全局变量的生命周期是:整个程序的生命周期

多说无益,各位可以尝试运行一下下面代码,就可以很清楚的知道代码的作用域与生命周期是说明意思了

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()        //简单来说变量在哪里可以使用哪里就是它的作用域
{                    
    {
        int a = 0;
        printf("%d", a);
    }
    printf("%d", a);
}

常量

C语言中定义的常量分为以下几种
1.字面常量
2.枚举常量
3.const修饰的常量
4.#define定义的标识符常量

  1. 字面常量

字面常量:就是你平常的数字类型,如以下

1 整型常量
1.0 浮点数常量
a 字符常量

2.枚举常量

以下图代码为例,各位可以尝试一下编译枚举常量

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
enum Sex   //enum是枚举常量的关键字定义在main函数外
{
MALE,
FEMALE,
SECRET,
};
//括号中的MALE,FEMALE,SECRET是枚举常量
int main()
{
printf("%d\n", MALE);
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
//枚举常量依次从0开始往下递减
return 0;
}

3.const修饰的常量

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
  const int a = 1;
  a = 2;   //这里会报错,即a不可修改
  printf(“%d”,a);
  return 0;
}

如上图可见const修饰的变量在语法上不可修改,而为什么说只是在语法上不能修改呢,因为其在本质上还是变量,彦祖请看

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
    const int a = 1;
    a = 2;   //这里会报错,即a不可修改
    int b[a] = {0}; 这说明了a本质还是变量
}

编译到这里的时候编译器就会告诉我们a要常量不能是变量,说明const只是在语法上不能被修改了

4.#define定义的标识符常量

#define定义的标识符常量是在main函数外面定义的,老规矩放入代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#define a 2
int main()
{
    int b[a] = {0,1};            
    for (int i = 0; i < 2; i++)
    {
        printf("%d", b[i]);    //这里说明了denfine本质上改变了变量->常量
    }
    return 0;
}

字符串与转义字符

1.字符串

字符串通俗来说就是你键盘上的东西都可以为字符,字符串就是多个字符。而在C语言中怎么定义单个字符与字符串呢

char a='a';
char arr[]="abcde";

简单来说,定义字符用单引号,定义字符串用双引号,用数组来装下

值得注意的是:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()            //\0是字符串的停止标志,b只是多字符的数组,加上\0为字符串
{                        //窗口监视里明显可以看见b最后没有0 F10-调试-窗口-监视
    char a[]={ "abc" };
    char b[] = { 'a','b','c' };
    printf("%s\n", a);
    printf("%s", b); 
    return 0;           //简单看的出来\0才停止b数组只是多字符的数组加                        
}

感兴趣的彦祖们可以将上面代码实现,不难发现会出来以下内容

你会问了,为什么b数组会出来这么多乱码呢,那是因为b数组后面没有\0,本质是多个字符组成的数组,而不是字符串,你要打印b数组的字符串模式,电脑要找到\0才能停止,故打印abc后电脑会自动往下随机打印,直到遇到\0。

那怎么才能使b数组只打印出abc呢,各位可以思考下

ok解决了字符串的打印问题,我们来看看怎么肉眼证明\0是字符串的结束标志,还是老代码,通过监视窗口实现,F10-调试-窗口-监视这是判断你代码的好工具。

2.转义字符

各位彦祖,这里我值写下我认为几个注意的地方

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
    printf("c:\test\test.c\n");
    printf("c:\\test\\test.c\n");
    //说明了在写路径时使用\\以免转义为tab
    return 0;
}

各位可以实现一下这些代码的输出,你就会发现有什么不一样了

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
    printf("c:\test\test.c\n");
    printf("c:\\test\\test.c\n");
    //说明了在写路径时使用\\以免转义为tab
    printf("%d", strlen("c:\test\test.c\n"));
    //你切记转义字符都只算一个长度\n这样都算
    return 0;
}

strlen是计算你字符串长度的工具,大家可以实现前想一想,c:\test\test.c\n一共是多少长度,聪明的你可能会想\t是空格的转义,那么我们就要加上空格的长度,\n是下一行的转义,这要怎么算呢。

可以看出来c:\test\test.c\n的长度是13。为什么是这个长度?我只能说

你切记,所有转义字符都看作一个长度

类似的

printf("%d", strlen("c:\test\628\test.c\n"));
//你看这里是15 \628你转8进制怎么转?只能算\62。
\ddd转8进制,读取1-3个数字,能读多就读多,这里的\628由于读不进去8(八进制里没有八)就只读取了62.

/与%的区别

/是求商的意思,%是取余的意思,我们用代码说话

int main()                    //15/2=7...1
{
    printf("%d\n", 15 / 2);    //你切记/是求商的值->7
    printf("%d", 15 % 2);    //%求余数->1 
    return 0;
}

看到这里,我们思考一下我们在求一个数能不能被5整除的时候应该用/5还是%5?

值得注意的是,在我们小%大时候是=小的

int main()
{
    printf("%d", 2 % 3);    //输出2
    return 0;
}
%的一个有趣用法: 我们任何一个随机数%n,得到的结果一定是0-n之间的数,如我们的的一个随机数m%100,得到的结果肯定是在0-100(左闭右开)区间的,这个用法在后面的rand函数里经常实现

sizeof与strlen的区别

老规矩我们先看代码

int main()
{
    int arr[] = { 1,2,3,4 };
    printf("%d\n", sizeof(arr));    //16
    printf("%d\n", sizeof(arr[0]));    //4
    //sizeof计算的是内存,即所占空间大小,单位是字节。arr为int型,int占4字节

    char arr1[] = { "abcd" };
    printf("%d\n", sizeof(arr1));    //5
    printf("%d\n", strlen(arr1));    //4
    //sizeof是计算字符串的长度,空间大小,不在乎你存的什么
    //strlen是计算长度的,统计的是\0之前的
}
sizeof计算的是所占内存空间的大小,单位是字节,不在乎你内存里放的是什么(转义字符也算)
strlen是计算字符串的长度的,统计\0之前的字符个数

前置++与后置++的区别

int main()
{
    int a = 10;
    int b = 5;
    b = a++;                //后置的先使用再加加,先将10赋给b(使用),再++
    printf("%d\n", a);        //11
    printf("%d\n", b);        //10

    a = 10;
    b = 5;
    b = ++a;                //前置的先++后使用
    printf("%d\n", a);        //11
    printf("%d\n", b);        //11
    return 0;
}
我们理解到前置与后置区别就在于先使用还是先++,理解到什么是使用后就可以完美类比出我们的--了

ok我们已经理解了前置,后置与作用域,我们直接来看这题

void test()
{
    int a = 5;
    a++;
    printf("%d", a);
}

int main()
{
    int i = 0;
    while (i < 10)
    {
        test();
        i++;
    }
    return 0;
}

秒懂的老铁建议去读博,不懂的建议去实现一下代码,做到知行合一

其实答案并不是你的打印6-15或者是打印10个5,为什么呢?

这考的是我们对作用域,生命周期的理解,局部变量出作用域就会销毁,所以test函数里的a并不能保留。

常见的关键字

我们看到关键字的时候,应该与我们的之前的变量命名联想

这里我们提几个前期不常见的关键字

  • auto

是自动变量,何为自动?通俗来讲,你在创建局部变量的时候,在作用域内,内存会自动创建 这个变量,出作用域时,内存会自动销毁,这就是自动变量,由于所有变量都是自动变量,故 隐藏了。

  • typedef

顾名思义就是类型定义,理解为类型重定义

重新定义unsigned int类型为uint的意思,意为着你uint新类型就可以代替Unsigned int了

  • unsigned

为无符号定义,意思是说你的变量不能带有符号如“-1”就是有符号

  • extern

声明来自外部的符号,可以调用本工程内外部(.c文件)的变量,函数等,只需在前面加上extern,是外部链接属性的桥梁,如下图

  • static

我们在了解static之前先看下static的英文解释(点击查看)

顾名思义static有静止的意思,它的作用和它的意思相近

static的作用有3个
1.修饰局部变量
2.修饰全局变量
3.修饰函数

修饰局部变量

void test()
{
    static int a = 5;
    a++;
    printf("%d", a);
}
int main()
{
    int i = 0;
    while (i < 10)
    {
        test();
        i++;
    }
    return 0;
}

这个代码咱们还有印象吧,就是局部变量自动销毁。当我们加入的static之后我们打印可以看见

ok我们在解释前我们要知道,我们的内存分为栈区,堆区,静态区

我们总结一下,static修饰局部变量,改变了变量的存储类型,本来局部变量是放在栈中的,但被修饰后就放在内存中的静态区了,因为存储类型的改变,从而导致了生命周期的变长, 但是作用域不受影响。给我们的感觉是延迟了生命周期。

修饰全局变量

由于2个.c文件不好复制代码,用图片表示(对着extern图)

我们加上了static后发现,test.c不能调用变量了。

我们总结一下,static修饰全局变量时,将全局变量的外部链接属性改变成了内部链接属性,此时的全局变量只能在自己的.c文件使用。给我们的感觉是:影响了作用域。

修饰函数

ok老铁们我们有之前的例子,我们直接看代码,注意函数是有外部链接属性的。

与之前的修饰全局变量其实类似

我们总结一下,static修饰函数时,将外部链接属性改变成了内部链接属性,使之只能在自己的.c文件使用。

分支和循环

分支
  • if

  • switch

循环
  • while

  • do while

  • for

  • goto

控制语句用于控制程序的执行流程,以实现程序的各种结构方式(C语言支持三种结构:顺序结构、选 择结构、循环结构),它们由特定的语句定义符组成,C语言有九种控制语句。

可分成以下三类: 1. 条件判断语句也叫分支语句:if语句、switch语句; 2. 循环执行语句:do while语句、while语句、for语句; 3. 转向语句:break语句、goto语句、continue语句、return语句。

  1. if语句

if(表达式)
{
    语句
}

if语句中表达式是真就执行语句(0为假非0为中真)

我们if语句中主要2点需要注意,一点是在if语句中使用判断式,赋值,等于。另一点是else悬停问题

我们先看第一点,当你表达式中为这样的情况

if(18<=age<30)
{
    printf("青年");
}

ok,当我们的age=50的时候,你想我们程序不会执行整个语句,但事与愿违,电脑还是打印了青年,这是为什么呢?

因为这样的表达式从左往右依次判断,真为1假为0,程序进来,18小于等于age(50)吗?——真,为1——1小于30吗——真,为1。表达式中为1则执行下一步。

所以我们在使用这样的连续判断要加上我们的操作符(后面会详解操作符)

if(18 <= age && age < 30)

第一点中,我们还会遇到赋值和等于问题

==是等于
=是赋值

有时候我们的程序的分支语句得不到我们的结果,可能就是你把表达式中的等于变成了赋值,使其变为恒真了,为了避免整个问题,我们可以反写

if(5==a)
{
    语句
}

如这样,当我们反写的时候,只写一个等号,编译器会报错的,如果你不反写,等于写成了赋值,编译器也不会报错。这也是一个好习惯

第二点,else悬停问题,你只要记住,else与其离的最近的匹配

大家可以思考一下下图

这里什么都不输出,因为else和最后一个if匹配

  1. switch

switch(整型表达式)
{
    语句项;
    //是一些case语句:
//如下:
case 整形常量表达式:
    语句;

}

值得注意的是,我们的char也算作整型表达式里面的一员,因为它返回的是ascll值,使用我们用int来接受字符是绰绰有余的。而case中的整形常量表达式是对值得判断

好习惯:我们在写switch语句时,记得在每个 switch 语句中都放一条default子句是个好习惯,甚至可以在后边再加一个 break 。
如果表达的值与所有的case标签的值都不匹配怎么办?其实也没什么,结果就是所有的语句都被跳过而已。程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。

但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?你可以在语句列表中增加一条default子句,把下面的标签default:写在任何一个 case 标签可以出现的位置。
当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。所以,每个switch语句中只能出现一条default子句。但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。

我们可以看下这题思考一下输出的是什么

  1. 循环语句

这里我们先讲一个for循环

for(表达式1; 表达式2; 表达式3)
{
 循环语句;
}
表达式1 :为初始化部分,用于初始化循环变量的。
表达式2 :为条件判断部分,用于判断循环时候终止。
表达式3 :为调整部分,用于循环条件的调整。

循环语句中在后面会细讲,值得注意的是,continue与break,

break是跳出所在的循环中,不受if等语句限制

continue是跳过后面的语句,进入下一次循环

ok我们用前面的知识来一个测试

int main()
{
    int i = 1;
    while (i <= 10)
    {
        if (5 == i)
            continue;
        printf("%d ", i);
        i++;
    }
    return 0;
}

这里是先输出1 2 3 4然后就陷入死循环了,不懂的可以去调试

调试是你最好的老师

初始指针

1.内存编号

在这里我们是初始指针,了解关于指针的相关的概念及来源

在此之前我们先来了解一下电脑内存

1.内存被划分一个一个的内存单元,一个单元选择1字节
2.内存单元进行了编号

内存,就是你电脑软件运行的地方,划分编号(类比我们的房间号)方便查找

下面以32位电脑位例子-32地址线-有32bit位

多少位的机器上有多少位的地址线,每一个地址以通电产生高低电频即1与0,这就是产生了我们说的内存,如32位机器上可以有2^32种地址信号可能,我们把这种地址信号可能当作我们的内存单元编号。

一个地址管理一个内存单元(地址编号,地址编号有2^32个),内存单元通过地址线产生,而一个内存单元是1个字节。所以在32位机器上我们有2^32个字节的内存大小,换算为4G. 64位就是2^64字节8G 地址是地址,内存是内存,我们只是用地址信号管理我们的内存单元,不要混为一谈

2.变量地址取法

int main()
{
    int a = 0;
    printf("%p", &a); //%p为地址类型
    return 0;
}

如我们定义变量a=4,其实在内存里为a开辟了4个字节的内存大小(int类型占4字节),我们来看代码的运行结果

可以看但我们的地址是16进制表示的,老铁们会问了,不是每一个单元都有一个地址编号吗,为什么这里只显示了一个?

答:在C语言中我们如果开辟了是一块连续的空间,我们的地址是取其中最小的即起始地址作为整个 地址(为什么是这样的大家可以思考一下)

ok前面基础我们了解了这么多直接上指针

3.指针用法

在我们的C语言中,你切记地址就是指针,指针就是地址

指针的标识符就是*与&,如我们的int * pa=&a,int说明pa指向是int类型的,*表示你的pa是指针变量,指针变量指向地址,用&表示

我们看上图,指针变量pa指向了变量a的地址,我们要改变a的大小就可以通过pa来实现了,不过前面要加上我们的解引用操作符*

*pa=1; //代表这你a的值变为1了

4.指针变量内存大小

这是指针的基本操作,接下来我们来了解指针变量的内存大小

int main()
{
    printf("%d\n", sizeof(char*));
    printf("%d\n", sizeof(int*));
    printf("%d\n", sizeof(long*));
    printf("%d\n", sizeof(long long*));
    printf("%d\n", sizeof(float*));
    printf("%d\n", sizeof(double*));
    return 0;
}

还是那句话

秒懂的老铁建议去读博,不懂的建议去实现一下代码,做到知行合一

我们来看代码的运行

咦?为什么我的指针变量全是4字节,为什么和我想的不一样?

让我们来回想一下前面的内容,指针就是地址,地址就是指针!,ok既然如此,我们的一个地址存储要多大空间,我们的指针变量就需要多大的空间。
X86(32位平台)——32地址线——32bit位——一个地址大小4byte——指针就是4字节
X64(64位平台)是多少大家可以去算算
各位老铁能看到这,本人表示极度的感谢。若有帮助麻烦点个关注吧。路漫漫其修远兮,望共勉。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
目录 第1章 一大波数正在靠近——排序 1 第1节 zui快zui简单的排序——桶排序 2 第2节 邻居好说话——冒泡排序 7 第3节 zui常用的排序——快速排序 12 第4节 小哼买书 20 第2章 栈、队列、链表 25 第1节 解密QQ号——队列 26 第2节 解密回文——栈 32 第3节 纸牌游戏——小猫钓鱼 35 第4节 链表 44 第5节 模拟链表 54 第3章 枚举!很暴力 57 第1节 坑爹的奥数 58 第2节 炸弹人 61 第3节 火柴棍等式 67 第4节 数的全排列 70 第4章 wan能的搜索 72 第1节 不撞南墙不回头——深度优先搜索 73 第2节 解救小哈 81 第3节 层层递进——广度优先搜索 88 第4节 再解炸弹人 95 第5节 宝岛探险 106 第6节 水管工游戏 117 第5章 图的遍历 128 第1节 深度和广度优先究竟是指啥 129 第2节 城市地图——图的深度优先遍历 136 第3节 zui少转机——图的广度优先遍历 142 第6章 zui短路径 147 第1节 只有五行的算法——Floyd-Warshall 148 第2节 Dijkstra算法——通过边实现松弛 155 第3节 Bellman-Ford——解决负权边 163 第4节 Bellman-Ford的队列优化 171 第5节 zui短路径算法对比分析 177 第7章 神奇的树 178 第1节 开启“树”之旅 179 第2节 二叉树 183 第3节 堆——神奇的优先队列 185 第4节 擒贼先擒王——并查集 200 第8章 更多精彩算法 211 第1节 镖局运镖——图的zui小生成树 212 第2节 再谈zui小生成树 219 第3节 重要城市——图的割点 229 第4节 关键道路——图的割边 234 第5节 我要做月老——二分图zui大匹配 237 第9章 还能更好吗——微软亚洲研究院面试 243 啊哈算法 目 录 第1章 编程改变思维 1 第1节 为什么要学习编程 1 第2节 本书是讲什么的,写给谁看的 4 第2章 梦想启航 7 第1节 编程的魔力 7 第2节 让计算机开口说话 9 第3节 多彩一点 18 第4节 让计算机做加法 21 第5节 数字的家――变量 26 第6节 数据输出――我说咋地就咋地 31 第7节 数据输入――我说算啥就算啥 33 第8节 究竟有多少种小房子 37 第9节 拨开云雾见月明 40 第10节 逻辑挑战1:交换小房子中的数 42 第11节 天啊!这怎么能看懂 45 等等。。。。。。。。。。。。。。。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值