《深入探究C语言》系列——1.专题简介

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/admintan/article/details/50619885

《深入探究C语言》系列


c语言 作为一个科班出身的Coder可谓是神奇

一切似乎以他为起点 但多数人不会对他研究很深 和OIer或ACMer不同的是 大多数人太早的转向了面对对象语言也就是所谓的很强大的C# java python objc等等 一般人也不会去从底到顶的实现什么

但是 一些重要的 设计思维 编程思维 甚至编程习惯就这样被遗失了
试想想windows.h 里面的东西你知道多少? 倒不是说他们很重要 但是这样形成了一个空档

即 我们基本功在这种低级直接向高级跨越中丢失了很多 这也就是为什么 ACMer在工作中成长速度一般都超过常人很多

所以这个系列 我们将会从源头 去捡回c语言中

那些遗失的美好

从《深入理解计算机系统》,《操作系统》,《编译原理》这三本书所论述的角度深入理解

什么是编程 ,怎么编程

那么 show time

#include <stdio.h>
#include <math.h>
#include <windows.h>
#include <tchar.h>//微软制定的  ASCII和Unicode转换头文件
/*
如果我们这样写程序:  
                    _TCHAR *RetVal, *szString;     
                    RetVal = _tcsrev(szString);    
如果预编译系统定义了宏_UNICODE ,则上述代码被翻译成如下:                 
                   wchar_t *RetVal, *szString;                     
                     RetVal = _wcsrev(szString);


*/

float f(float x, float y, float z) {
    float a = x * x + 9.0f / 4.0f * y * y + z * z - 1;
    return a * a * a - x * x * z * z * z - 9.0f / 80.0f * y * y * z * z * z;
}

float h(float x, float z) {
    for (float y = 1.0f; y >= 0.0f; y -= 0.001f)
        if (f(x, y, z) <= 0.0f)
            return y;
    return 0.0f;
}


int main() {
    HANDLE o = GetStdHandle(STD_OUTPUT_HANDLE);

    //将其赋值为GetStdHandle((STD_OUTPUT_HANDLE)),即标准输出的句柄
    /*
    handle类型实际上是一个整形变量!
    windows操作系统==》操作系统(进程调度,内存管理,文件系统,设备管理等等)

    进程,文件和内存都有handle,handle作为一个索引让操作系统可以找到这些内核对象,
    可以认为是这些内核对象的ID
    进程的handle是pid,文件的handle是描述符,内存的handle是地址,外设的handlle。。
    */
    _TCHAR buffer[25][80] = { _T(' ') };


    /*
    char是C语言标准数据类型,字符型,至于由几个字节组成通常由编译器决定,一般一个字节。
    Windows为了消除各编译器的差别,重新定义了一些数据类型,你提到了另外几个类型都是这样。
    CHAR为单字节字符。还有个WCHAR为Unicode字符,即不论中英文,每个字有两个字节组成。
    如果当前编译方式为ANSI(默认)方式,TCHAR等价于CHAR,如果为Unicode方式,
    TCHAR等价于WCHAR。LPCSTR 相当于CONST CHAR * 和LPSTR 相当于CHAR *。
    */

    _TCHAR ramp[] = _T(".:-=+*#%@");

    /*
    _T("")是一个宏,他的作用是让你的程序支持Unicode编码
    因为Windows使用两种字符集ANSI和UNICODE,
    前者就是通常使用的单字节方式,
    但这种方式处理象中文这样的双字节字符不方便,
    容易出现半个汉字的情况。
    而后者是双字节方式,方便处理双字节字符。
    */



    for (float t = 0.0f;; t += 0.1f) {
        int sy = 0;
        float s = sinf(t);//弧度制
        float a = s * s * s * s * 0.2f;
        for (float z = 1.3f; z > -1.2f; z -= 0.1f)
        {

            _TCHAR* p = &buffer[sy++][0];

            float tz = z * (1.2f - a);


            for (float x = -1.5f; x < 1.5f; x += 0.05f)
            {
                float tx = x * (1.2f + a);
                float v = f(tx, 0.0f, tz);

                if (v <= 0.0f)
                {
                    float y0 = h(tx, tz);
                    float ny = 0.01f;
                    float nx = h(tx + ny, tz) - y0;
                    float nz = h(tx, tz + ny) - y0;
                    float nd = 1.0f / sqrtf(nx * nx + ny * ny + nz * nz);
                    float d = (nx + ny - nz) * nd * 0.5f + 0.5f;
                    *p++ = ramp[(int)(d * 5.0f)];
                }
                else
                    *p++ = ' ';
            }
        }

        for (sy  = 0; sy < 25; sy++) {
            COORD coord = { 0, sy };
            SetConsoleCursorPosition(o, coord);
            WriteConsole(o, buffer[sy], 79, NULL, 0);
        }

    /*
    COORD是一个结构体。
    typedef struct _COORD {
    SHORT X;
    SHORT Y;
    } COORD;
    X:横坐标;
    Y:纵坐标。
   */

        Sleep(33);//等待,参数表示 等待时间
    }
}

可以看到 这和我们日常学习的 c语言 有很大区别 因为 引入了 句柄
而这是我们 日常 学习中 一般不会去接触的类型

那么 这个代码究竟是用来干嘛的呢?

这里写图片描述
这里写图片描述

一颗跳动的红心

当然

控制台 我改动过

这是个跳动的心 其中利用了比较复杂的计算 和概念 来确定 在相应坐标上的 点应该是哪个字符

今后的这个系列 将会着眼于一些 c语言的编程技巧和思维 以及一些c语言的妙用

see you~(这么短的博客真的不是来灌水的么哈哈哈)

猜你喜欢

转载自blog.csdn.net/admintan/article/details/50619885