[HLSL]HLSL 入门参考 (dx11龙书附录B译文)

原文:[HLSL]HLSL 入门参考 (dx11龙书附录B译文)

HLSL 高级着色语言 参考文档

龙书DirectX12现已推出中文版,其附录B的高级着色器语言参考的翻译质量比本文更高,有条件的读者可以去支持一下。

目录

文章目录

  • 目录
  • 变量类型
    • 标量类型
    • 矢量类型
      • Swizzles
    • 矩阵类型
    • 数组
    • 结构体
    • typedef 关键字
    • 变量前缀
    • 类型转换 (Casting)
  • 关键字 和 (运)算符
    • 关键字
    • (运)算符
  • 流程语句
  • 函数
    • 自定义函数
    • 内建函数
  • 译注

变量类型

标量类型

  1. bool: 值为 true 或 false. 注意 HLSL 像 C++ 一样,提供 true 和 false 关键字以供使用.
  2. int: 32位有符号整数
  3. half: 16位有理数(浮点数)
  4. float: 32位有理数
  5. double: 64位有理数

Note: 一些平台可能不支持 int, half, 或 double. 这些平台会使用 float 来模拟.

矢量类型

  1. float2: float 组成的二维矢量.
  2. float3: float 组成的三维矢量.
  3. float4: float 组成的四维矢量.

Note: 可以将 float 替换成其他标量类型以组成新的矢量. 比如 int2, half3, bool4.

??可以通过像给数组或结构体初始化那样初始化矢量:

float3 v = {1.0f, 2.0f, 3.0f};
float2 w = float2(x, y);
float4 u = float4(w, 3.0f, 4.0f);
// u= (w.x, w.y, 3.0f, 4.0f)

??可以通过数组下标的语法访问矢量元素. 比如访问矢量 vec 的第i个元素,可以这样写:

vec[i] = 2.0f;

??另外,可以通过定义好了的元素名 x, y, z, w, r, g, b 和 a 像访问结构体那样访问矢量元素.

vec.x = vec.r = 1.0f;
vec.y = vec.g = 2.0f;
vec.z = vec.b = 3.0f;
vec.w = vec.a = 4.0f;

?? 名称 r, g, b 和 a 与名称 x, y, z 和 w 引用的元素完全一样. 当用矢量表示颜色时,使用符号RGBA会更好一些,因为这强调了矢量储存的是颜色的事实.

Swizzles

??有时候会要使用矢量 u=(ux,uy,uz,uw)\mathbf{u}=(u_x,u_y,u_z,u_w)u=(ux?,uy?,uz?,uw?) 的元素来填充矢量 v=(uw,uy,uy,ux)\mathbf{v}=(u_w, u_y, u_y, u_x)v=(uw?,uy?,uy?,ux?) .最直接的方法就是分别引用每个元素来分别赋值.不过 HLSL 提供了一种叫 Swizzles 的特殊的语法来进行这种仅仅变换次序的赋值:

float4 u = {1.0f, 2.0f, 3.0f, 4.0f};
float4 v = {0.0f, 0.0f, 5.0f, 6.0f};
v = u.wyyx;
//v = {4.0f, 2.0f, 2.0f, 1.0f}

??另一个例子:

float4 u = {1.0f, 2.0f, 3.0f, 4.0f};
float4 v = {0.0f, 0.0f, 5.0f, 6.0f};
v = u.wzyx;
// v = {4.0f, 3.0f, 2.0f, 1.0f}

??如果只需要复制部分元素的话可以这样子:

float4 u = {1.0f, 2.0f, 3.0f, 4.0f};
float4 v = {0.0f, 0.0f, 5.0f, 6.0f};
v.xy = u;
// v = {1.0f, 2.0f, 5.0f, 6.0f}

矩阵类型

??可以使用下列语法定义 m × n 的矩阵,其中 n 和 m 必须在 1 到 4 之间:

floatmxn matmxn;

??例如:

  1. float2x2: float 型元素组成的 2 × 2 矩阵.
  2. float3x3: float 型元素组成的 3 × 3 矩阵.
  3. float4x4: float 型元素组成的 4 × 4 矩阵.
  4. float3x4: float 型元素组成的 3 × 4 矩阵.

Note: 可以将 float 替换成其他标量类型以组成新的矩阵. 比如 int2x2, half3x3, bool4x4.

??可以使用两个数组下表的语法访问矩阵元素.例如访问 i 行 j 列元素:

M[i][j] = value;

??另外还可以像结构体那样访问矩阵元素:

// One-Based Indexing:
// 索引从1起计数
M._11 = M._12 = M._13 = M._14 = 0.0f;
M._21 = M._22 = M._23 = M._24 = 0.0f;
M._31 = M._32 = M._33 = M._34 = 0.0f;
M._41 = M._42 = M._43 = M._44 = 0.0f;

// Zero-Based Indexing:
// 索引从0起计数
M._m00 = M._m01 = M._m02 = M._m03 = 0.0f;
M._m10 = M._m11 = M._m12 = M._m13 = 0.0f;
M._m20 = M._m21 = M._m22 = M._m23 = 0.0f;
M._m30 = M._m31 = M._m32 = M._m33 = 0.0f;

??有时候会需要引用矩阵的行矢量出来.可以只用一个数组下标来引用行矢量.比如从 3 × 3 矩阵 M\mathbf{M}M 中提出第i行的行矢量可以这样子:

float3 ithRow = M[i];
// 获取第i行行矢量

??下面的例子演示了向矩阵中插入三个矢量:

float3 N = normalize(pIn.normalW);
float3 T = normalize(pIn.tangentW - dot(pIn.tangentW, N)*N);
float3 B = cross(N,T);
float3x3 TBN;
TBN[0] = T; // 设置第 1 行行矢量
TBN[1] = B; // 设置第 2 行行矢量
TBN[2] = N; // 设置第 3 行行矢量

??还可以从行矢量生成矩阵:

float3 N = normalize(pIn.normalW);
float3 T = normalize(pIn.tangentW - dot(pIn.tangentW, N)*N);
float3 B = cross(N,T);
float3x3 TBN = float3x3(T, B, N);

Note:四维矢量和 4 × 4 矩阵除了可以用 float4 和 float4x4 表示,还可以直接用 vector 和 matrix 表示:

vector u = {1.0f, 2.0f, 3.0f, 4.0f};
matrix M; // 4 x 4 矩阵

数组

??可以用熟悉的 C++ 语法声明一个数组,例如:

float M[4][4];
half p[4];
float3 v[12]; // 12 个三维矢量

结构体

??结构体同样可以像 C++ 那样定义.不过 HLSL 的话就不允许有成员函数.这是一个结构体的例子:

struct SurfaceInfo {
    float3 pos;
    float3 normal;
    float4 diffuse;
    float4 spec;
};
SurfaceInfo v;
litColor += v.diffuse;
dot(lightVec, v.normal);
float specPower = max(v.spec.a, 1.0f);

typedef 关键字

??HLSL 的 typedef 跟 C++ .的几乎完全一样.例如给 vector<float,3> 一个别名可以这样:

typedef float3 point;

??然后可以将这样子的写法:

float3 myPoint;

改写成:

point myPoint;

??这是另外一个将 const 关键字(用起来跟C++一样的)进行 typedef 的演示:

typedef const float CFLOAT;

变量前缀

??以下关键字可以添加到变量前面作为前缀:

  1. static: 本质上讲是 extern 的反义词;这个关键字表示该变量不会暴露给 C++ ,是仅着色器程序内部可见的变量.

    static float3 v = {1.0f, 2.0f, 3.0f};

  2. uniform: 表示变量不改变每一个顶点或像素—使得变量对于所有顶点和像素都是常量,只能在 C++ 改变其值.变量只能在着色器程序外部初始化(例如从 C++)
  3. extern: 表示变量在 C++ 可见(例如 C++ 程序可在着色器程序外部访问这个变量).这里的全局变量默认为 uniform 和 extern.
  4. const: 该关键字与 C++ 的 const 关键字一样.表示该变量为常量,不可改变.

    const float pi = 3.14f;

类型转换 (Casting)

??HLSL 允许数据进行类型转换,而且类型检查非常宽松.HLSL的类型转换跟 C 语言的相似.例如,转换 matrix 为 float 可以这样:

float f = 5.0f;
float4x4 m = (float4x4)f;
// 给 m 的每一个元素赋 f

??标量到矩阵的类型转换会将标量给矩阵的的每一个元素都用这个标量赋值.看看下面的例子:

float3 n = float3(...);
float3 v = 2.0f*n - 1.0f;

?? 2.0f*n 是标量与矩阵的数乘,没有问题.然而要使式子成立,标量 1.0f 会扩充成矢量 (1.0f, 1.0f, 1.0f).因此式子相当于:

float3 v = 2.0f*n - float3(1.0f, 1.0f, 1.0f);

??这里的例子都能容易地推断出类型转换的情况.不过完整的类型转换规则还是得参阅 SDK 参考文档,搜索 “Casting and Conversion”.

关键字 和 (运)算符

关键字

??为了方便参考,现在列出 HLSL 所有的关键字:

- - - -
asm float pass true
bool for pixelshader typedef
compile half return uniform
const if sampler vector
decl in shared vertexshader
do inline static void
double inout string volatile
else int struct while
extern matrix technique
false out texture

??下面的关键字保留且未使用,未来可能成为正式关键字.

- - - -
auto dynamic_cast private template
break enum protected this
case explicit public throw
catch friend register try
char goto reinterpret_cast typename
class long short union
const_cast mutable signed unsigned
continue namespace sizeof using
default new static_cast virtual
delete operator switch -

(运)算符

??HLSL支持很多熟悉的 C++ 关键字. 除了下面要提到的少数的相异点,这些算符用起来跟 C++ 一毛一样.下表列出了所有的 HLSL 的算符.

- - - - - -
[ ] . > < <= >=
!= == ! && || ? :
+ += - -= * *=
/ /= % %= ++
= ( ) ,

??虽然这些算符用起来跟 C++ 很像,但是还是有相异点.

  1. 取模 % 算符可以在整数和有理数(浮点数)下工作.但是要进行取模,两个操作数要求要符号统一(比如都为正数或都为负数).
  2. 有到很多 HLSL 算符能对矢量或矩阵的每个元素单独进行,这是因为矢量和矩阵都内建在 HLSL 内部了,而且这些类型都由多个元素组成.通过使这些算符能对每个元素单独进行操作,可以扩展原本只能对标量进行运算的算符的用途,使它们支持矢量/矩阵分量加法,矢量/矩阵分量减法,矢量/矩阵相等性测试等.看下面的例子:

Note:像是在 C++ 里的一样,这些算符的行为可从它对标量的运算里猜出来.

float4 u = {1.0f, 0.0f, -3.0f, 1.0f};
float4 v = {-4.0f, 2.0f, 1.0f, 0.0f};
// 矢量分量加法(各元素相加)
float4 sum = u + v; // sum = (-3.0f, 2.0f, -2.0f, 1.0f)

??矢量分量自增(各元素自增)

// 自增前: sum = (-3.0f, 2.0f, -2.0f, 1.0f)
sum++;
// 自增后: sum = (-2.0f, 3.0f, -1.0f, 2.0f)

??矢量分量乘法

float4 u = {1.0f, 0.0f, -3.0f, 1.0f};
float4 v = {-4.0f, 2.0f, 1.0f, 0.0f};
// 矢量分量乘法(各元素相乘)
float4 product = u * v; // product = (-4.0f, 0.0f, -3.0f, 0.0f)

Warning: 对于两个矩阵

float4x4 A;
float4x4 B;

操作 A*B 会进行分量乘法,而非矩阵乘法,矩阵乘法需要用函数 mul 进行.

??比较算符同样会对每个元素进行,并且返回由 bool 型值组成的(布尔)矢量或矩阵. bool 型值会填充整个作为运算结果的矢量或矩阵.例如:

float4 u = { 1.0f, 0.0f, -3.0f, 1.0f};
float4 v = {-4.0f, 0.0f, 1.0f, 1.0f};
float4 b = (u == v);
// b = (false, true, false, true)

??最后,对二元算符可以做如下断定的结论:

  1. 如果二元算符的左操作数与右操作数的维度不同,那么维度小的操作数会被类型转换到其维度与另一个操作数的维度一致,这被称为 提升.例如, float 型的 x 和 float3 型的 y 进行 (x + y) 操作时, x 会被类型转换为 float3 型矢量,表达式最终结果的类型为 float3 型,其中 float 型的 x 类型会 提升 成 float3(x, x, x),这也是因为标量到矢量的类型转换预定好的.注意:对于未有定义类型转换的 提升 将会失败.例如, float2 到 float3 的 提升 将会失败,因为不存在矢量 float2 到矢量 float3 的类型转换.
  2. 如果二元算符的左操作数与右操作数的类型不同,那么类型 low 的一方的类型会被 提升 到与另一方相同.例如, int 型的 x 与 half 型的 y 进行 (x + y) 操作时, x 会被 提升 为 half 型,表达式最终结果的类型为 half.

流程语句

??HLSL 支持许多熟悉的 C++ if 语句,循环语句及其他常见的控制流程的语句.这些流程语句的语法跟 C++ 超像.

  • 返回语
return (expression);
  • if 语句
if(condition) {
    statement(s);
}
  • if else 语句
if(condition) {
		statement(s);
} else {
	statement(s);
}
  • for 语句
for(initial; condition; increment) {
	statement(s);
}
  • while 语句
while(condition) {
	statement(s);
}
  • do while 语句
do {
	statements(s);
}while(condition);

函数

自定义函数

??HLSL 的函数有以下特点:

  1. 用起来跟 C++ 很像.
  2. 参数跟在变量后面1
  3. 不支持递归
  4. 全都是内联函数

??并且 HLSL 还添加了给自定义函数用的额外的关键字.比如下面这个函数:

bool foo(
    in const bool b, // input bool
    out int r1, // output int
    inout float r2 // input/output float
) {
    if(b) { // 试探输入的数据
        r1 = 5;
        // 通过 r1 输出
    } else {
        r1 = 1;
        // 通过 r1 输出
    }
    // 因为 r2 为 inout 所以可以用它作为 输入, 即读取数据
    // 也可通过 r2 输出
    r2 = r2 * r2 * r2;
    return true;
}

??函数几乎就跟 C++ 的一样除了 in, out 和 inout 关键字.

  1. in: 在函数体执行之前,指示函数调用的该参数值会被复制一份副本给函数体来使用.一般没必要明确加上 in 因为参数默认就是 in.例如下面这两个例子等价:
float square(in float x) {
	return x * x;
}

??去掉 in :

float square(float x) {
	return x * x;
}
  1. out: 指示函数返回后会将函数体对该参数所有赋值应用到调用函数时的此处的变量.即好似直接对外部变量的引用操作,但是不可读.需要这个特性时这个关键字不能缺,因为 HLSL 不允许传递引用或指针.
void square(in float, out float) {
	y = x * x;
}

??通过 x 输入一个要被平方的数,并用 x 自乘得到平方并通过 y 返回值.

  1. inout: in 和 out 的组合. 如果需要同时作为 in 和 out,那么用 inout.
void square(inout float x) {
	x = x * x;
}

??通过 x 输入一个存有要被平方的数的变量,并用 x 自乘得到平方并通过 x 返回值.

内建函数

??HLSL 有用于 3D 图形编程的丰富的内建函数.下面列出部分内建函数:

  1. abs(x) - 返回 ∣x∣|x|∣x∣.
  2. ceil(x) - 返回最小的大于等于x的整数.
  3. cos(x) - 返回 cosxcos xcosx,其中 x 为弧度.
  4. clamp(x, a, b) - 修剪 x, 若 x 大于 b,则返回 b;若 x 小于 a,这返回 a,否则返回 x.
  5. clip(x) - 仅可在像素着色器中调用,如果输入向量中的任何元素小于0,则丢弃当前像素.
  6. cross(u, v) - 返回 u×v\mathbf{u} \times \mathbf{v}u×v
  7. ddx§ - Estimates screen space partial derivative ?p/?x. This allows you to determine how per pixel quantities p vary from pixel

    to pixel in the screen space x-direction.

  8. ddy§ - Estimates screen space partial derivative ?p/?y. This allows you to determine how per pixel quantities p vary from pixel

    to pixel in the screen space y-direction.

  9. degress(x) - 将弧度 x 转为角度
  10. determinant(M) - 返回矩阵的行列式的值
  11. distance(u, v) - 返回作为点的 u 和 v 的距离.
  12. dot(u, v) - 返回 u?v\mathbf{u} \cdot \mathbf{v}u?v.
  13. floor(x) - 返回最大的小于等于 x 的整数.
  14. frace(x) - 返回有理数(浮点数)的小数部分.
  15. length(x) - 返回 ∥v∥\rVert\mathbf{v}\rVert∥v∥.
  16. lerp(u, v, t) - 在 u 和 v 之间插值,要求 t∈[0,1]t \in [0,1]t∈[0,1],v > u 时返回 u+(v?u)tu+(v-u)tu+(v?u)t.
  17. log(x) - 返回 lnxln xlnx.
  18. log10(x) - 返回 log10xlog_{10}xlog10?x.
  19. log2(x) - 返回 log2xlog_2xlog2?x.
  20. max(x, y) - 返回 max{x,y}max\{x, y\}max{x,y}.
  21. min(x, y) - 返回 min{x,y}min\{x, y\}min{x,y}.
  22. mul(M, N) - 返回矩阵乘法 MN\mathbf{M}\mathbf{N}MN.注意要使该乘法要有意义.若 M 为矢量,则该函数为行矢量左乘矩阵.若 N 为矢量,则该函数为列矢量右乘矩阵.
  23. normalize(v) - 返回 v/∥v∥\mathbf{v}/\rVert\mathbf{v}\rVertv/∥v∥.
  24. pow(b, n) - 返回 bnb^nbn.
  25. radians(x) - 将角度 x 转为弧度
  26. saturate(x) - 返回 clamp(x, 0,0, 1.0).
  27. sin(x) - 返回 sinxsin xsinx.
  28. sincos(in x, out s, out c) - 通过 s 返回 $ sin x$, 通过 c 返回 cosxcos xcosx,其中 x 为弧度.
  29. sqrt(x) - 返回 x\sqrt{x}x?.
  30. reflect(v, n) - 返回 v 在以 n 为法向量的平面上反射的向量.
  31. reflact(v, n, eta) - 返回 v 在以 n 为法向量的 eta 为折射率的平面上折射的向量.
  32. rsqrt(x) - 返回 1x\frac{1}{\sqrt{x}}x?1?.
  33. tan(x) - 返回 tanxtan xtanx,其中 x 为弧度.
  34. transpose(M) - 返回转置矩阵 MT\mathbf{M}^TMT.
  35. Texture2D::Sample(S, texC) - Returns a color from a 2D texture map based on the SamplerState object S, and 2D texture coordinates texC.
  36. Texture2D::SampleLevel(S, texC, mipLevel) - Returns a color from a 2D texture map based on the SamplerState object S, 2D texture coordinates texC, and mipmap level mipLevel. This function differs from Texture2D::Sample in that the third parameter manually specifies the mipmap level to use. For example, we would specify 0 to access the topmost mipmap LOD.
  37. TextureCube::Sample(S, v) - Returns a color from a cube map based on the SamplerState object S and 3D lookup vector v.
  38. Texture2DArray::Sample(S, texC) - Returns a color from a 2D texture array based on the SamplerState object S (recall a sampler state specifies texture filters and texture address modes) and 3D texture coordinates texC, where the first two coordinates are the usual 2D texture coordinates and the third coordinate specifies the array index.

Note: 很多函数都根据它应该能处理的数据重载了,使之能处理所有应该能处理的内建类型的参数.例如 abs 应当能处理所有标量数据,因故重载了对所有标量类型的操作.另外就是外积 cross 函数应当只能处理三维矢量,所以它就只重载了对所有标量类型的三维矢量的操作(例如 int3, float3, double3 等).还有就是线性插值函数 lerp 应该能处理所有标量,二维矢量,三维矢量和四维矢量的数据,所以它重载了这些所有类型的操作.

Note: 如果给"标量"函数(例如 cos(x))一个非标量的参数,该函数会遍历所有元素,对所有元素都调用该函数.例如:

float3 v = float3(0.0f, 0.0f, 0.0f);
v = cos(v);

会对所有元素都调用 cos 函数.

Note: 关于更多参考文档,完整的内建函数清单请查阅 DirectX 参考文档,搜索 “HLSL Intrinsic Functions.”

译注

  • 仅供教研学习交流用,不准一声不响拿去闷声发大财.
  • 配合 Introduction to 3D Game Programming with DirectX 11龙书dx11译文版 享用风味更佳.
  • 中国的3D编程处境好惨啊.
  • 对了,译者四级还没过.

  1. Parameters are always passed by value. ??

原文地址:https://www.cnblogs.com/lonelyxmas/p/10807273.html

时间: 2024-11-05 22:32:49

[HLSL]HLSL 入门参考 (dx11龙书附录B译文)的相关文章

龙书11_chapter_4 一: GameTime解读

看龙书DX11,首先是第四章,本文对GameTime类进行解释 问:此类主要实现了什么功能? 答:Returns the total time elapsed since Reset() was called, NOT counting any time when the clock is stopped. 从渲染窗口Reset开始记时,记录总共的时间.不包括此间的pause时间. 问:关键时间接口? 答: 1. //获取频率(取决于主板 OS相关,不是CPU的主频)参考:http://www.

龙书常见错误解决方案

龙书简单地看了一遍,但是大部分内容只能勉强弄懂原理,一些算法只知其然而不知其所以然.不过饭还是要一口一口地吃,图形学的一些算法需要自己多多积累学习探索,早日成竹在胸.游刃有余. 龙书中例子都很经典,但是不少例子无法编译成功,下面就是一些常见的解决方案: ①将字符集改为使用多字节字符集,这样可以解决无法从“const char”转换为“LPCWSTR”问题,当然也可以在所有字符串前面加上TEXT(). ②CD3DFont也可以使用,但是编译错误会很多,比如经典的strcpy问题,以及众多类似问题.

新编html网页设计从入门到精通 (龙马工作室) pdf扫描版?

新编html网页设计从入门到精通共分为21章,全面系统地讲解了html的发展历史及4.0版的新特性.基本概念.设计原则.文件结构.文件属性标记.用格式标记进行页面排版.使用图像装饰页面.超链接的使用.使用表格组织页面.使用多媒体美化页面.创建多框架页面.动态网页的制作.使用层叠样式表(css)美化页面.javascript语言.数组和字符串以及表达式与程序的流程控制等内容. 本书适合作为培训学校的教材,也可供想要把网页做得更好的广大普通网页制作爱好者学习,以及从事网站建设和网页设计的专业人士参考

编程经典书籍:龙书、虎书、魔法书

书不在多,而贵在于精. 编程界也有很多经典书籍,而且这些经典书籍很多都有一个霸气的别名,如编译原理领域有"龙书""虎书""鲸书"的说法,听起来是不是瞬间高大上了. 其实,这些书的别名主要根据封面.作者姓名首字母.书名首字母来命名的.下面,我们就来盘点下编程界的龙书.虎书.鲸书.橡书.犀牛书.蝴蝶书...都是指哪些 首先来看看依据封面命名的书籍: 编译原理三大圣书 1.<编译原理>(龙书) 想要学习C/C++可以私信回复"学习

龙书学习笔记(二)

补线代之余抽空把第四章上色学了,之所以说之余,是因为这一章内容确实不怎么多,不过为了巩固知识,便结合刚学的上色又做了一个小程序. 首先进行回顾,这一章学到的一共有四点: 一.Direct3D中颜色用RGB(Red.Green.Blue)三元组表示,用两种结构来保存 D3DCOLOR,即unsigned long,共32位,分成4个8位项,分别保存Alpha(这玩意的作用会在第七章学到).红.绿.蓝,均在0x00~0xff之间取值(就是0~255) 通过结构体来保存(D3DXCOLOR和D3DCO

【龙书笔记】语法分析涉及的基础概念简介

本篇笔记是我对龙书第2.3-2.5节内容的理解,主要介绍编译器前端关于语法分析的众多基础概念.下篇笔记将根据本篇笔记的主要内容,实现一个针对简单表达式的后缀式语法翻译器Demo(原书中是java实例,我给出的将是逻辑一致的Python版本的实现). 1. 语法分析(Syntax Analysis) 简单来说,语法分析的任务是分析输入的符号字符串(string of symbols, 通常是词法分析产生的tokens)是否遵循某种语言在其上下文无关文法(context-free grammar)中

【龙书笔记】编译器简介及程序构建过程综述

备注:本文是近期重新阅读编译器经典教材<Compilers Principles, Techniques, & Tools>一书(又称DragonBook,龙书)的其中一篇读书笔记. 1. 什么是编译器 从本质来看,平时提到的"编程语言"其实都是一些助记符,用于向其他人或机器描述我们想要完成的逻辑运算.这些易于人类理解的语言想要被计算机理解并正确执行,就必须被转换成机器码,而完成这一转换过程的软件系统就是编译器. 简言之,编译器其实也是一个计算机程序,它可以读取用一

平实给力的写作指导入门手册——leo鉴书57

写作是个体力活儿,需要不断的练习和砥砺.既然是体力劳动,那必然有套路,前人总结.后人学习并加以积累沉积,日久则形成不同的风格和流派有点儿像.同样,写作也有自己的套路和学习路径.初涉写作有必备之书吗?当然有,那就是<<华尔街日报>是如何讲故事的>这本. 我妈是语文老师,从小写作.语文对我就是种折磨.06年我改变主意开始写作时先是写博文,当时被朋友总结的写作风格是"简单粗暴 毫不矫情",意思是全以自己为中心,写得又硬又没人味儿,自然愿意读的人不多(相当部分是被我拉来

龙书(Dragon book) +鲸书(Whale book)+虎书(Tiger book)

1.龙书(Dragon book)书名是Compilers: Principles,Techniques,and Tools作者是:Alfred V.Aho,Ravi Sethi,Jeffrey D.Ullman国内所有的编译原理教材都是抄的它的,而且只是抄了最简单的前端的一些内容.龙书中文版第一版龙书英文版第二版 2.鲸书(Whale book)书名是:Advanced Compiler Design and Implementation作者是:Steven S.Muchnick也就是高级编译