zoukankan      html  css  js  c++  java
  • 从基础学起----xuld版高手成长手记[1]

    别人的代码总是看不懂?

    想实现一个功能总是无从下手?

    学会一个,但稍微变个花样就不知道了?

    无论你擅长什么编程语言,如果你觉得自己基础薄弱,想从头开始学起,那本文将适合你。

    这篇文章的含金量非常高,如果你有一种恍然大悟的感觉,那恭喜,你进步了。

    学基础,到底学啥?

    菜鸟都会说学汇编啊,学C语言啊。

    有一个人初学编程,学什么语言好?

    菜鸟都会说它自己正在用的语言是最好的。

    标准答案:

    学基础,主要学计算机程序的工作方式。语言仅仅是一个工具,真正的高手无论什么语言都能写出好代码。

    初学编程,学什么语言。首先我并没有否定ruby, java,但是如果你真的是准备学好编程的,那必须从C开始学。

    很多人学 C 语言都是学它的语法,因为很多C的教程就是这么教的。但单单学语法是不对的。

    学习程序的运行原理是学好编程的关键。

    你知道一个进程占用的内存都用在哪了吗?

    你知道函数递归调用的死循环错误为什么叫做栈溢出错误吗?

    你知道为什么有些程序运行时会突然卡一会么?

    第一章 计算机基本原理

    一 、二进制

    二进制是计算机存储数据的格式。如果对二进制不了解,可以网上找相关资料。

    二、计算机组成

    计算机由以下部件组成:

    1. 中央处理器(CPU)

    2. 存储器(如内存卡、硬盘)

    3. 输入输出设备(如鼠标、键盘、显示器)

    计算机有且仅有计算和存储二进制数据的功能。

    三、计算机数据存储

    计算机的数据可以存在三个地方:

    寄存器(属于CPU的一部分)

    内部存储(常称内存)

    外部存储(如硬盘、光盘、U盘)

    现在一些显卡也可存储数据,称为显存,它也可以理解为内部存储。

    CPU 可以直接从寄存器读写数据以及计算,但是它是无法直接读写外部存储的。要想让CPU访问外部存储,必须编写相应的驱动程序来实现。

    为了方便应用软件读写任意位置的数据,操作系统为这一过程作了一层包装。简单地说,当程序需要读取文件时,会先通知操作系统,然后操作系统再调用相应的驱动程序来读取数据。

    四、数据格式

    由于计算机只能存储二进制数据,因为存储各式各样的数据,需要作一些转换。

    1. 存储一个数字

    任何数字都可以直接用二进制保存。

    2. 存储一个文本

    为了存储一个文本,先制定一个文本到数字的编码表,如规定使用 59 表示字母 'A',这样所有文本都可以用数字保存。

    编码表可以是任意的,但为了全球计算机都能统一理解,因此人们制定了很多编码规范,常见的有: ASCII, UTF-8, Unicode, GB2312  。

    3. 存储一个图片

    图片可以理解为很多不同颜色的点。分别存储这些点的颜色值即可。比如一张100*200像素的图片,就需要存储100*200=20000个像素点。每个点都用一个数字表示一个颜色值。这种存储方式叫做位图(bitmap),即bmp图片。这样存储一个图片需要的空间是非常大的,因此人们发明了很多可以压缩存储的格式。

    4. 存储其它数据

    理论上,任何数据都可以通过编码的方式保存,只不过好的编码方式更节约空间。所以现在计算机存在这么多文件格式,也是人们不断探索更优秀编码方式的结果。

    五、数据类型

    单从一个二进制数据段,我们是无法猜测它表示的意义的。它可能就是一个数字,也可能就是一个文字或者其它。因此我们需要制定一些数据类型来描述一个数据的意义。

    不同的编程语言有不同的类型分类。脚本语言表面上没有数据类型,但其实语言执行器内部已经对类型进行严格管理了。

    六、关于本章提到的与未提到的

    本章只对一些概念作了介绍,并未对这些概念内部细节作介绍。因为我们的目标是利用好计算机,而不是去发明一个计算机,因此这些细节原理完全可不理会,我们只需享受前人的研究成果即可。

    第二章 C语言基础

    我对写C教程没有兴趣,但是学习C语言可以更好地理解计算机内部工作原理,因此,写C代码是不可少的过程。

    一、准备

    搭建一个C环境很简单,个人推荐初学的人下载 dev-cpp。初学者可以试着运行如下 hello world 代码,运行的目的只是为了证明你的学习环境已经准备好。

    #include<stdio.h>
    int main(){
        printf("hello world");
        return 0;
    }

    二、基础类型

    在C语言里面,基础类型有:

    类型名大小表示意义
    char 8 ASCII 字符
    short 16 16位整数
    int 32 32位整数
    long 32 32位整数
    long long 64 64位整数
    float 32 单精度小数
    double 64 双精度小数

    其中,所有的整数类型默认都是有符号的(即区分正负),在类型名前加 unsigned 可以得到无符版本。

    > 如何表示无符64位整数?

    unsigned long long

    > 如何表示有符16位整数?

    short

    三、常量

    常量也叫字面量。C语言的常量有:

    常量内容示例类型
    普通的整数 0 int
    普通的小数 4.6 double
    0x开头的十六进制整数 0xff int
    单引号包括的单个字符 'a' char

    > 常量 .33333 是什么类型

    double

    四、变量

    计算机中的数据可以存储到寄存器、内存或外部存储。其中,寄存器的使用是由C编译器自动控制的。

    为了读写内存,C语言发明了“变量”的概念,一个变量即表示内存中的一块区域。如通过声明一个 int 类型的变量,就可以读写内存中的某个32位大小的区域。

    声明变量的语法格式为:(其中变量名可以是任意字母组合,变量名不可重复)

    类型 变量名;

    > 如何声明一个用于存储 16 位整数的变量?

    short a;

    五、表达式

    表达式即数学上的计算式。C中的表达式可以是:常量、变量、运算表达式(具体下文介绍)。

    运算是根据一个表达式计算得到一个值的过程,运算是计算机的基本能力。根据运算数个数的不同,运算可分为单目运算、双目运算和三目运算。

    1. 直接赋值

    变量名 = 表达式

    通过赋值,可以将数据存储到变量。

    > 如何声明一个 int 类型的变量然后赋值为 2?

    int a;
    a = 2;

    > 如何声明2个 char 类型的变量,第一个变量赋值为 'a',第2个变量赋值为第一个变量的值。

    char c1;
    c1 = 'a';
    
    char c2;
    c2 = c1;

    任何变量在赋值前,其值是随机的。

    2. 算术运算

    算术运算即 +(加)、-(减)、*(乘)、/(除)、%(余)。我们需要关心的是类型的变化。

    类型变化准则(按顺序,如果满足1,则不往下看)

    1. 如果计算的表达式有一个是 double,则返回 double

    2. 如果计算的表达式有一个是 float,则返回 float

    3. 如果计算的表达式有一个是 unsigned long long,则返回 unsigned long long

    4. 如果计算的表达式有一个是 long long,则返回 long long

    5. 如果计算的表达式有一个是 unsigned int,则返回 unsigned int

    6. 剩下情况全部返回 int

    > float 类型变量 + double 类型变量返回什么类型?

    double

    >3 + 5 =?

    8

    >4.7 +5.3 =?

    10.0 (注意10是错误的)

    > 8/7 = ?

    1 (因为只能得到int,所以使用舍尾法)

    公式:a % b = a + ceil(a / b) * b (其中 ceil(x) 表示不大于 x 的最大整数)

    > 3.2 % 2.6 =?

    = 3.2 + ceil(3.2 / 2.6) * 2.6 = 3.2 + 1 * 2.6 =  0.6

    + - 也可作为单目运算使用,分别表示正、负。如:

    int a;
    a = 1;
    a = -a;

    3. 比较运算

    比较运算即 >(大于) <(小于) >=(不小于) <=(不大于) ==(等于) !=(不等于)

    比较类型总是返回 0 或者 1。对于字符,返回其等效数值的比较结果。

    4. 位运算

    位运算只能用于整数。位运算有:<<(左移) >>(右移) &(位与) |(位或) ^(位异或) ~(位反,这是单目运算)

    类型变化准则(按顺序,如果满足1,则不往下看)

    1. 如果计算的表达式有一个是 unsigned long long,则返回 unsigned long long

    2. 如果计算的表达式有一个是 long long,则返回 long long

    3. 如果计算的表达式有一个是 unsigned int,则返回 unsigned int

    4. 剩下情况全部返回 int

    0000 0001 << 1 = 0000 0010     二进制所有位数左移 1 位,左边多余的删除,右边缺少的补 0
    0000 0001 >> 1 = 0000 0000     二进制所有位数右移 1 位,右边多余的删除,左边缺少的,如果是无符就补 0,否则补符号位。

    0000 0001 & 0000 0001 = 0000 0001     每位二进制依次比较,如果有一个0则返回0,否则返回1
    0000 0001 | 0000 0001 = 0000 0001      每位二进制依次比较,如果有一个1则返回1,否则返回0
    0000 0001 ^ 0000 0001 = 0000 0000     每位二进制依次比较,如果相同则返回1,否则返回0
    ~0000 0001=1111 1110        每位二进制取反,如果原来是0则返回1,否则返回0

    >3 << 2 =?

    先将3转为二进制:00000000 00000000 00000000 00000011

    然后左移2位:000000 00000000 00000000 0000001100

    然后转为十进制: 12

    公式: a * 2 = a << 1

             2x = 1 << x

             a << y = a * (1 << y) = a * 2y 

            -a = ~a + 1

            ~a = -a - 1

    > ~77 = ?

    -78

    > 1<<8 = ?

    256

    > 如何计算一个 int 第 6 位 二进制是 1 还是   0

    > 如何判断一个 int 第8 和 第 3 位 二进制有一个是 1

    > 如何判断一个 int 第8 和 第 3 位 二进制都是 1

    > 如何设置一个 int 的第 3 位为 1

    > 如何设置一个 int 的第 3 位为 0

    > 输入一个 int,如何输出这个 int的二进制格式。如 输入 2,输出 00000000 00000000 00000000 00000010

    5. 布尔运算

    布尔运算有:&&(与) ||(或) !(非,单目运算)

    布尔运算总是返回 0 或 1。

    1 && 1 = 1      如果操作数都非零,则&&返回 1,否则返回0

    0 || 0 = 0        如果操作数都零,则||返回 0,否则返回1

    !0 = 1            如果操作数非零,则!返回 0,否则返回1

    6.其它运算

    为了简化 a = a + 2 的写法,c语言还可使用 a += 2简写它。

    为了简化 a = a + 1的写法,c语言还可使用 a++ 简写它。

    表达式可以互相嵌套,各个表达式都有计算的优先级,如先算乘法,再算加法。可以使用括号来强制使某个表达式先计算。

    >1 + 2 * 5 = ?

    11

    >1 + +1 =?

    =1 + (+1) = 1 + 1 = 2

    > (1 << 3) + 2 = ?

    10

    7. 类型转换

    类型转换是将指定类型的变量等效转为其它类型的操作。语法格式为:

    (新类型)表达式

    > 定义声明一个 double ,然后转为 short

    double a;
    short c;
    c = (short)a;

    位数低的类型可以自动转为位数高的类型,这个过程叫隐式转换。通过如上语法的转换叫显式转换。

    如果本来需要显示转换的地方,使用了隐式转换,C编译器会提供一个警告。

    8. 指针

    任何变量在内存都有固定的位置,为了方便处理根据位置处理数据,C引入了指针的概念。

    一般地,我们可以简单认为指针是表示数据在内存的地址。通过指针可以间接读写其它位置的数据。

    根据指针指向的数据意义,指针又分为不同的类型。如指向一个存储 int 类型数据的指针,其类型为 int*,如指向一个存储 char 类型数据的指针,其类型是 char*,如果不确定其指向的数据的实际类型,则可以使用void*来表示。

    指针本身的大小是32位(64位电脑是64位)

    变量是内存中的一个数据,它当然是有地址的,要获取一个变量的地址,可以使用如下格式:

    &变量名

    要设置一个指针指向的数据的值,可以使用如下格式:

    *指针 = 表达式;


    > 声明一个 int 类型的变量,然后创建一个执行此变量的指针,然后通过此指针为这个变量赋值为 1。

    int a;
    int* addr;
    
    addr = &a;
    
    *addr = 1;

    ******待续******


    我自己擅长 C++/C#/JavaScript,也用过 PHP/VB/Ruby/NodeJs。

    我认为:一个项目,80%的代码不需要考虑性能,20%的代码需要考虑。
    全部用 C++ 非常麻烦,全部用 Java 又无法满足性能,而且容易被反编译。
    这就是我开发 Tea 的目标。

    我不会说服任何人使用这门语言,因为这对我没有好处。

    我只是希望这门语言可以发挥作用,帮助开发出优秀的软件。


  • 相关阅读:
    从零开始——PowerShell应用入门(全例子入门讲解)
    详解C# Tuple VS ValueTuple(元组类 VS 值元组)
    How To Configure VMware fencing using fence_vmware_soap in RHEL High Availability Add On——RHEL Pacemaker中配置STONITH
    DB太大?一键帮你收缩所有DB文件大小(Shrink Files for All Databases in SQL Server)
    SQL Server on Red Hat Enterprise Linux——RHEL上的SQL Server(全截图)
    SQL Server on Ubuntu——Ubuntu上的SQL Server(全截图)
    微软SQL Server认证最新信息(17年5月22日更新),感兴趣的进来看看哟
    Configure Always On Availability Group for SQL Server on RHEL——Red Hat Enterprise Linux上配置SQL Server Always On Availability Group
    3分钟带你了解PowerShell发展历程——PowerShell各版本资料整理
    由Find All References引发的思考。,
  • 原文地址:https://www.cnblogs.com/xuld/p/3578934.html
Copyright © 2011-2022 走看看