`
icheng
  • 浏览: 821198 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
文章分类
社区版块
存档分类
最新评论

3D 图形编程的数学基础(2) 矩阵及其运算

 
阅读更多

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

讨论新闻组及文件

Technorati 标签: 3D,matrix,irrlich,D3D,DirectX,math

矩阵(matrix)的概念

由m * n 个数有序地排成m行n列的数表,称为一个m行n列的矩阵,一般用大写表示。全零的称为零矩阵。

以下是一个 4 × 3 矩阵:

/begin{bmatrix}
1 & 2 & 3 //
1 & 2 & 7 //
4&9&2 //
6&1&5/end{bmatrix}

某矩阵 A 的第 i 行第 j 列,或 i,j位,通常记为 A[i,j] 或 Ai,j。在上述例子中 A[2,3]=7。(来自wikipedia

当一个矩阵仅包含单行或单列时,这样的矩阵就称为行向量或列向量。(参考上一篇《3D 编程的数学基础(1) 向量及其运算》)

GNU Octave(matlab):

A =

   16    2    3   13
    5   11   10    8
    9    7    6   12
    4   14   15    1
上面就是用GNU Octave(matlab)生成的一个4*4的矩阵。

事实上,在Irrlicht与DirectX中,都只有4*4的矩阵,原因以后再讲,在Irrlicht中矩阵用模板类CMatrix4<t>表示,并且有</t>

typedef CMatrix4<f32> matrix4;</f32>

DirectX中的矩阵是用D3DXMATRIX表示,并且功能上设计的比D3D中的矩阵会多很多。

在DirectX中,此结构继承自以下结构。

typedef struct _D3DMATRIX {
union {
struct {
float _11, _12, _13, _14;
float _21, _22, _23, _24;
float _31, _32, _33, _34;
float _41, _42, _43, _44;

};
float m[4][4];
};
} D3DMATRIX;

也就是说,在DirectX中以m[4][4]的二维数组来表示4*4的矩阵。与Irrlicht不同,在Irrlicht中是用T M[16];来表示的。但是使用上大致相同,因为都重载了()操作符,可以以A(i, j)的方式来获取矩阵A的第i行,第j列的值。

比如,我们有一个如下的矩阵。

E =

    1    2    3    4
    5    6    7    8
    9   10   11   12
   13   14   15   16

D3D中构造及遍历的代码如下:

#include <stdio.h></stdio.h>#include <d3dx9.h></d3dx9.h>int _tmain(int argc, _TCHAR* argv[])
{
    D3DXMATRIX A(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);

    for(int i = 0; i i)
    {
        for(int j = 0; j j)
        {
            printf("%.2f/t", A(i, j));
        }
        printf("/n");
    }

    return 0;
}

结果:

1.00    2.00    3.00    4.00
5.00    6.00    7.00    8.00
9.00    10.00   11.00   12.00
13.00   14.00   15.00   16.00

Irrlicht中

#include <stdio.h></stdio.h>#include <irrlicht.h></irrlicht.h>using namespace irr::core;

int _tmain(int argc, _TCHAR* argv[])
{
    matrix4 A;
    float m[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
    A.setM(m);

    for(int i = 0; i i)
    {
        for(int j = 0; j j)
        {
            printf("%.2f/t", A(i, j));
        }
        printf("/n");
    }

    return 0;
}
输出结果一样。

行优先及列优先(选读,与数学无关,仅与计算机存储矩阵的物理方式有关)

在D3D及Irrlicht中,顺序的输出矩阵,是先遍历行,然后再遍历列,这种方式叫行优先或者行主序(row-major order),这里特意提出来是因为事实上还有先遍历列然后遍历行的存储方式,称为列优先或者列主序(Column-major order)。给大家一个参考资料(Wikipedia的Row-major_order

D3D中的遍历:(需要强转成FLOAT数组后然后遍历)

for(int i = 0; i i)
{
    printf("%.2f/t", ((FLOAT*)A)[i] );
}
Irrlicht中的遍历:
for(int i = 0; i i)
{
    printf("%.2f/t", A[i]);
}

假如大家全部用行优先的存储方式,那么我就不用再多费口舌讲列优先了,事实上,OpenGL就采用了列优先的存储方式,呵呵,似乎OpenGL生来就是与这个世界相反的的,坐标系D3D,Irrlicht用右手坐标系吧,OpenGL就偏偏用左手坐标系,D3D,Irrlicht用行优先存储矩阵吧,OpenGL就偏偏用列优先方式存储矩阵。。。。。用长沙话来说,这叫逗霸。。。(当然,其实从历史来说,应该是这个世界与OpenGL唱反调才对)

在OpenGL中,没有为矩阵设计结构,仅用数组表示(也体现了OpenGL的底层和原始),假如用glLoadMatrix*来加载一个矩阵的话,此矩阵应该是这样排列的:

 1    5    9   13
 2    6   10   14
 3    7   11   15
 4    8   12   16

郁闷了吧。。。。。。。。。

矩阵加减,数乘

与向量类似,这里也不多描述了。也就是对应元素的简单加减乘操作。概念非常简单,不多描述了。看看实际的操作。

GNU Octave(matlab):

> B = A + A
B =

   32    4    6   26
   10   22   20   16
   18   14   12   24
    8   28   30    2

octave-3.2.3.exe:7:d:
> C = B - A
C =

   16    2    3   13
    5   11   10    8
    9    7    6   12
    4   14   15    1

octave-3.2.3.exe:8:d:
> D = A * 2
D =

   32    4    6   26
   10   22   20   16
   18   14   12   24
    8   28   30    2

可以看到C = A和D = B = A + A = C * 2,对应元素的计算,非常简单。事实上D3D,Irrlicht中的矩阵类都已经重载了相关的运算符,直接使用即可。

矩阵的转置(Transpose)

矩阵的转置可通过交换矩阵的行和列来实现。所以,一个m*n矩阵的转置是一个n*m矩阵。我们用yyyy_html_7bb96079来表示矩阵M的转置。

设A为m×n阶矩阵(即m行n列),第i行j列的元素是a_ij,即:A=(a_ij)

直观来看,将A的所有元素绕着一条从第1行第1列元素出发的右下方45度的射线作镜面反转,即得到A的转置。一个矩阵M, 把它的第一行变成第一列,第二行变成第二列,......,最末一行变为最末一列,从而得到一个新的矩阵N。这一过程称为矩阵的转置。

基本性质

(以下T都是上标)

(A±B)T=AT±BT

(A×B)T= BT×AT

(AT)T=A

在GNU Octave(matlab)中,有现成的转置函数:

> A
A =

   1   2   3   4

octave-3.2.3.exe
> transpose(A)
ans =

   1
   2
   3
   4
上面也体现了转置最常用的用法,将行向量转为列向量。再看个矩阵的例子。
> E
E =

    1    2    3    4
    5    6    7    8
    9   10   11   12
   13   14   15   16

octave-3.2.3.exe:67:
> transpose(E)
ans =

    1    5    9   13
    2    6   10   14
    3    7   11   15
    4    8   12   16

将E的计数增长行列交换了,假如保持获取元素的下标与上述计数增长一致,事实上相当于将行优先转化为列优先,这也是实际中转置的一种用途。

比如在OpenGL中使用列优先,但是假如我们有的都是行优先数据怎么办?可以通过加载转置矩阵的方式加载,即

glLoadTransposeMatrix*函数。

在D3D中由函数D3DXMatrixTranspose实现转置。

在Irrlicht中实现转置的代码如下:

    // returns transposed matrix
    template class T>
    inline CMatrix4T> CMatrix4T>::getTransposed() const
    {
        CMatrix4T> t ( EM4CONST_NOTHING );
        getTransposed ( t );
        return t;
    }


    // returns transposed matrix
    template class T>
    inline void CMatrix4T>::getTransposed( CMatrix4T>& o ) const
    {
        o[ 0] = M[ 0];
        o[ 1] = M[ 4];
        o[ 2] = M[ 8];
        o[ 3] = M[12];

        o[ 4] = M[ 1];
        o[ 5] = M[ 5];
        o[ 6] = M[ 9];
        o[ 7] = M[13];

        o[ 8] = M[ 2];
        o[ 9] = M[ 6];
        o[10] = M[10];
        o[11] = M[14];

        o[12] = M[ 3];
        o[13] = M[ 7];
        o[14] = M[11];
        o[15] = M[15];
#if defined ( USE_MATRIX_TEST )
        o.definitelyIdentityMatrix=definitelyIdentityMatrix;
#endif
    }

理解上应该很简单,因为转置本身就很简单。

矩阵乘法

矩阵乘法被参考1称为3D图形学中最重要的运算,没有之一。

它只有在第一个矩阵的列数(column)和第二个矩阵的行数(row)相同时才有定义。若Am×n矩阵,Bn×p矩阵,则他们的乘积AB会是一个m×p矩阵。其乘积矩阵的元素如下面式子得出:

 (AB)_{ij} = /sum_{r=1}^n a_{ir}b_{rj} = a_{i1}b_{1j} + a_{i2}b_{2j} + /cdots + a_{in}b_{nj}.

矩阵乘法不符合交换率,所以将 AB 称为矩阵A右乘B ,或B左乘A。

其实上述的代数方程,已经一些解释都非常难以理解,比如“Wikipedia矩阵乘法”上的讲解,讲了半天,倒是把我快绕晕了。我见过最易懂的解释来自于参考1,AB的第ij个元素值等于A的第i个行向量与B的第j个列向量的点积。点积的概念参考参考上一篇向量的知识,因为使用了更高一级的名词(更为抽象),所以更好理解,比教你怎么去拼,怎么去记公式要好。

简单的说:image3

先设定函数dotp以计算行向量A与列向量B之间的点积。

function ret = dotp (A, B)
ret = sum(A .* transpose(B))
end

endfunction

验证一下我们自己写的函数:

> A
A =

   1   2   3   4

octave-3.2.3.exe
> B
B =

    1
    5
    9
   13

octave-3.2.3.exe
> dotp(A,B)
ret =  90
ans =  90

此时,用带上点积的定义实现两个向量的矩阵乘法函数,如下:

function ret = mul (A, B)
for i = 1 : length(A)
for j = 1 : length(B)
ret(i,j) = dotp(A(i,1:length(A)), B(1:length(B), j))
end
end

endfunction

同样验证一下:

E =

    1    2    3    4
    5    6    7    8
    9   10   11   12
   13   14   15   16

octave-3.2.3.exe:72:d:/Oc
> F
F =

   1   1   1   1
   2   2   2   2
   3   3   3   3
   4   4   4   4

octave-3.2.3.exe:73:d:/Oc
> mul(E,F)
octave-3.2.3.exe:74:d:/Oc
> M = mul(E,F)
octave-3.2.3.exe:75:d:/Oc
> M
M =

    30    30    30    30
    70    70    70    70
   110   110   110   110
   150   150   150   150

octave-3.2.3.exe:76:d:/Oc
> E * F
ans =

    30    30    30    30
    70    70    70    70
   110   110   110   110
   150   150   150   150

这里,我们用我们高层抽象的定义实现了mul函数,并且通过验证,个人感觉,这样的定义更加容易记忆,见仁见智,且当一家之言吧。

不然,你愿意这样记住公式也行。。。。。见Irrlicht的矩阵乘法实现:(除了数量的乘法,没有牵涉进其他概念,一个一个去对一下,看看头晕不晕。)

    //! multiply by another matrix
    // set this matrix to the product of two other matrices
    // goal is to reduce stack use and copy
    template class T>
    inline CMatrix4T>& CMatrix4T>::setbyproduct_nocheck(const CMatrix4T>& other_a,const CMatrix4T>& other_b )
    {
        const T *m1 = other_a.M;
        const T *m2 = other_b.M;

        M[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3];
        M[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3];
        M[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3];
        M[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3];

        M[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7];
        M[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7];
        M[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7];
        M[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7];

        M[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11];
        M[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11];
        M[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11];
        M[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11];

        M[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15];
        M[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15];
        M[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15];
        M[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
#if defined ( USE_MATRIX_TEST )
        definitelyIdentityMatrix=false;
#endif
        return *this;
    }

方阵

行数与列数相同的矩阵称为方阵。比如,上述4*4的矩阵其实都是方阵(就如同矩形是长,宽可以不一样,正方形边长一样),并且,方阵的行数(列数)称为它的阶,上述4*4的矩阵可以被称为4阶方阵,也是3D图形编程中使用的最多的矩阵。

单位矩阵

主对角线上元素为1,其他元素为0的方阵,称为单位矩阵。(Identity Matrix)一般以I表示,单位矩阵在矩阵算法中相当于普通数学运算的1。

I_1 = /begin{bmatrix}
1 /end{bmatrix}
,/ 
I_2 = /begin{bmatrix}
1 & 0 //
0 & 1 /end{bmatrix}
,/ 
I_3 = /begin{bmatrix}
1 & 0 & 0 //
0 & 1 & 0 //
0 & 0 & 1 /end{bmatrix}
,/ /cdots ,/ 
I_n = /begin{bmatrix}
1 & 0 & /cdots & 0 //
0 & 1 & /cdots & 0 //
/vdots & /vdots & /ddots & /vdots //
0 & 0 & /cdots & 1 /end{bmatrix}

一个单位矩阵与某个矩阵相乘,不改变该矩阵。

在GNU Octave(matlab)中,也有现成的函数可以获取单位矩阵:

> eye(4)
ans =

Diagonal Matrix

   1   0   0   0
   0   1   0   0
   0   0   1   0
   0   0   0   1

在Irrlicht中,获取单位矩阵就更简单了,默认的matrix4类,就是单位矩阵。

在D3D中通过函数:

D3DXINLINE D3DXMATRIX* D3DXMatrixIdentity
( D3DXMATRIX *pOut )

获取

逆矩阵

设A是数域上的一个n阶方阵,若在相同数域上存在另一个n阶矩阵B,使得:AB=BA=I,则我们称B是A的逆矩阵,而A则被称为可逆矩阵,可逆矩阵也被称为非奇异矩阵、非奇异矩阵、满秩矩阵。

1.可逆矩阵一定是方阵

2.一个可逆矩阵的逆矩阵是唯一的

3.两个可逆矩阵的乘积依然可逆

4.可逆矩阵的转置矩阵也可逆

正交矩阵(我数学书上都没有的概念-_-!)

n阶实矩阵 M称为正交矩阵,如果:M×yyyy_html_7bb96079=I (定义yyyy_html_7bb96079表示“矩阵M的转置矩阵”。)

则下列诸条件是等价的:

1) M 是正交矩阵

2) M×yyyy_html_7bb96079= I 为单位矩阵

3) yyyy_html_7bb96079是正交矩阵

4) M的各行是单位向量且两两正交

5) M的各列是单位向量且两两正交

6) (Mx,My)=(x,y) x,y∈R

参考资料:

1.《DirectX 9.0 3D游戏开发编程基础》 ,(美)Frank D.Luna著,段菲译,清华大学出版社

2.《大学数学》湖南大学数学与计量经济学院组编,高等教育出版社

3.百度百科及wikipedia

其实这些概念都没有什么难的,大学中的线性代数课程中的基本概念而已,我不过想拿来结合GNU Octave(matlab)及D3D,Irrlicht一起来复习一下而已,下一篇预计讲解矩阵变换,应该也是最后一篇了。

原创文章作者保留版权 转载请注明原作者 并给出链接

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

<script type="text/javascript">var sitebro_tracker_atc_kw = {u:'http://www.sitebot.com.cn/754892/',w:'NzU0ODky',bt:'#804000',bg:'#EEEEDD',fs:1,ca:'#770000',bh:'#f4f4c6',cp:'',l:10,s:1,lang:'zh_CN'};</script><script type="text/javascript" src="http://www.sitebot.com.cn/js/widget_track2/tracker_atc_kw.js"></script><script type="text/javascript"><!-- var sitebro_tracker_atc={u:'http://www.sitebot.com.cn/754892/',w:'NzU0ODky',bt:'#804000',bg:'#EEEEDD',cf:'#ffffff',ca:'#770000',bh:'#DDDDCC',cp:'%E6%9C%AC%E7%AB%99%E7%83%AD%E9%97%A8%E6%96%87%E7%AB%A0',l:10,s:0,lang:'zh_CN'}; // --></script><script src="http://www.sitebot.com.cn/js/widget_track2/tracker_atc.js" type="text/javascript"></script>
分享到:
评论

相关推荐

    3D数学基础 图形与游戏开发

    《3D数学基础:图形与游戏开发》主要介绍了基本的3D数学概念,这对电脑游戏开发人员和编程人员来说尤为重要。作者详尽地讨论了数学理论,并在必要时提供几何说明,帮助读者形成直观的3D感。书中还提供了将理论应用于...

    OpenGL图形变换时的矩阵和向量计算数学库GLM

    在使用OpenGL做图形加载后,根据实际需求往往需要进行平移、旋转、缩放等操作,在三维坐标中,通过矩阵和向量之间的各种数学运算完成以上过程。glm包含了丰富的矩阵、向量计算数学库。在用此数学库之前,需要有一定...

    DirectX9 3D游戏设计入门 英文版+中文版+源代码

    传说中的龙书是也。。。 最好最新的DirectX游戏开发入门书籍 ...Prank Luna是Hero lnteractive的程序员,从事交互式3D图形编程已有八年多。他最早接触DirectX可以追溯到DirectX5发布之时,目前居住在加州的洛杉矶市。

    数学实验题目(十五题,matlab基础编程题)(答案见另一资源)

    matlab的相关基础操作题目(一共十五题),涉及MATLAB基本运算,矩阵的创建,矩阵的运算,多项式求导、求根、求值等运算,数值函数求值、求零点、求最大最小值、求定积分,数值函数作图,符号变量和符号表达式的创建...

    精品教程 MATLAB程序设计教程 MATLAB与高等数学 第01章 MATLAB操作基础(共33页).ppt

    MATLAB程序设计教程 MATLAB与高等数学 第02章 MATLAB矩阵及其运算(共78页).ppt MATLAB程序设计教程 MATLAB与高等数学 第03章 MATLAB程序设计(共48页).ppt MATLAB程序设计教程 MATLAB与高等数学 第04章 MATLAB...

    数学实验答案(十五题,matlab基础编程题)(题目见另一资源)

    matlab的相关基础操作题目(一共十五题),涉及MATLAB基本运算,矩阵的创建,矩阵的运算,多项式求导、求根、求值等运算,数值函数求值、求零点、求最大最小值、求定积分,数值函数作图,符号变量和符号表达式的创建...

    matlab教学ppt

    目标:了解MATLAB,能够熟练掌握数学(矩阵)运算,简单编程,简单的数据处理及基本图形绘制. 课程的主要内容一、MATLAB操作基础二、MATLAB矩阵及其运算三、MATLAB程序设计四、MATLAB文件操作五、MATLAB绘图六、...

    精品教程 MATLAB程序设计教程 MATLAB与高等数学 第09章 MATLAB符号计算(共23页).ppt

    MATLAB程序设计教程 MATLAB与高等数学 第02章 MATLAB矩阵及其运算(共78页).ppt MATLAB程序设计教程 MATLAB与高等数学 第03章 MATLAB程序设计(共48页).ppt MATLAB程序设计教程 MATLAB与高等数学 第04章 MATLAB...

    精品教程 MATLAB程序设计教程 MATLAB与高等数学 第03章 MATLAB程序设计(共48页).ppt

    MATLAB程序设计教程 MATLAB与高等数学 第02章 MATLAB矩阵及其运算(共78页).ppt MATLAB程序设计教程 MATLAB与高等数学 第03章 MATLAB程序设计(共48页).ppt MATLAB程序设计教程 MATLAB与高等数学 第04章 MATLAB...

    MATLAB图像处理与界面编程宝典pdf part4

     第5章 矩阵运算及优化  第6章 颜色和三维物体描述  第7章 MATLAB的光照与材质   第8章 透明度及纹理贴图  第9章 灵活的交互操作  第10章 科学计算可视化 第2部分 图像处理工具箱详解  第11章 图像...

    MATLAB平常小练习

    1. **基础数学运算**:MATLAB内置了各种数学函数和运算符,支持矩阵运算、微积分、线性代数、概率统计等基础数学操作,是进行数学小练习的理想工具。 2. **数据可视化**:MATLAB的图形绘制功能强大,可以轻松创建二...

    matlab实习报告(1).doc

    MATLAB 上机实习报告书 这学期进行了MATLAB的实习,在为期几天的实习中,大家实习了MATLAB基本操作 、值数组及其运算、ATLAB图形绘制基础和SIMULINK仿真基础。同时通过这些也了解 了MATLAB的基本情况和它的众多优点...

    matlab-实习报告.doc

    MATLAB实习报告 这学期进行了MATLAB的实习,在为期几天的实习中,大家实习了MATLAB基本操作 、值数组及其运算、ATLAB图形绘制基础和SIMULINK仿真基础。同时通过这些也了解 了MATLAB的基本情况和它的众多优点。 一、...

    MATLAB教程

    第 2 节 Matlab编程 5 一、 矩阵(数组)的输入 5 二、 矩阵元素的访问及其大小的确定 6 三、 矩阵的算数运算 6 四、 关系运算 6 五、 逻辑运算 6 六、 集合运算 7 七、 MatLab的控制流 7 第二章 符号数学工具...

    Matlab实用教程

    第2~3章介绍MATLAB基于命令窗口的应用,讲述了MATLAB的基础知识和数学运算;第4~8章介绍MATLAB基于M文件的应用,讲述了MATLAB的编程功能、数据显示及存取功能、数值和符号计算功能、图形用户界面设计功能等;第9~...

    精通matlab6.5

    2.7 数组运算的矩阵运算 2.8 多项式的表达方式及其操作 2.9 标准数组生成函数和数组操作函数 2.10 数组构作技法综合 2.11 高维数组 2.12 “非数”和“空”数组 2.13 关系操作和逻辑操作 第三章 字符串、元胞和构架...

    计算方法与软件应用

    它不仅具有强大的数值计算功能,可以处理如:矩阵计算、微积分运算、各种方程的求 解、插值和拟合计算、完成各种统计和优化问题,最新的版本甚至可以进行数字图象处理、小波分析等;同时它还有方便的画图功能和完善...

    《APDL参数化有限元分析技术及其应用实例》[PDF]

    apdl的基本要素包括支持apdl的菜单操作、变量、数组与表参数及其用法、数据文件的读写、数据库信息的访问、数学表达式、使用函数编辑器和加载器、矢量与矩阵运算、内部函数、流程控制、宏与宏库以及定制用户图形界面...

    精通matlab7光盘内容分享-精通matlab7源程序.rar

    基础入门、matlab桌面、数组及其操作、多维数组及其操作、数据类型概述和数值类型、结构体和元胞数组、字符串、关系运算和逻辑运算、程序控制流、函数、m文件调试和剖析、目录管理和文件i/o、matlab中的时间、矩阵...

    C语言经典源代码实例 数据结构 操作系统 图形等

    第一部分 基础篇 001 第一个C程序 002 运行多个源文件 003 求整数之积 004 比较实数大小 005 字符的输出 006 显示变量所占字节数 007 自增/自减运算 008 数列求和 009 乘法口诀表 010 猜数字游戏 011 ...

Global site tag (gtag.js) - Google Analytics