C语言程序分析

C语言程序分析,第1张

程序的分析,都从main()函数说起:

main函数开始定义了5个变量a,b,c,d,p;

puts表示输入提示,第一个输入的是a,第二个输入的是b;

do表示循环大括号内的内容;现在进入大括号内部:

输出 :input operation:

getchar()表示输入一个字符,编译器用字符规则去判定;输入的字符复制给p

if 表示判断语句 :如果……

if(p=='+') add(a,b,c):如果输入的符号是加号“+”则执行add(a,b,c)函数。这里面add是函数调用,它代表了一组功能,具体的功能在上面的add里面写得很清楚了。是将a+b的值给c 最后输出c

同理if(p=='-') minus(a,b,c);else :如果输入的符号是“-”,执行minus(a,b,c)函数,具体函数功能见minus(a,b,c)函数,c=a-b 并把c输出

if(p=='') multiplication(a,b,c);else…………

if(p=='/') div(a,b,d)………………

一个道理。

总结:

这个程序完成的是四则运算,首先输入两个数字,再输入一个运算符,程序会根据输入的运算符进行相应的运算;如果输入的运算符不是加、减、乘、除中的一个,则提示“没有注册这个运算符号”;当输入为0时,程序退出。

SUB02:

CMP STR+1,2;str+1即为str下面的字节里的内容

JNB Y2

JMP QUIT;字符串的长度低于2的话就退出

Y2: CALL LINE

@Y2: XOR AX,AX

MOV CNT1,AX

MOV CNT5,AX

;cnt1用来控制左边的空格数

;cnt5用于控制右边的空格数

MOV DL,60-2

MOV AL,STR+1

SUB DL,AL;58的意思是下面的小黄框框里面最大能放58个字符。放完用户输入的字符后剩余的位置个数给dl。

MOV DH,0

MOV CNT3,DX

;意思是把上面的dl保存到变量cnt3里面去

;cnt3表示左边字符和右边字符之间的空格数

MOV BL,AL

INC AL

SHR AL,1

CBW

MOV CNT2,AX

;把用户输入的字符个数一分为二。

;cnt2表示左边有多少个字符

SUB BL,AL

MOV BH,0

MOV CNT4,BX

;cnt4右边多少个字符

Y3: MOV BP,ES

PUSH DS

POP ES

MOV DI,1000H

MOV CX,CNT1

JCXZ U1

MOV AL,20H

REP STOSB

U1: LEA SI,BUF

MOV CX,CNT2

REP MOVSB

;把左边的字符转移到数据段中偏移地址为1000h的位置

MOV CX,CNT3

JCXZ U2

MOV AL,20H;20h的ASCII码为空格

REP STOSB

;把左右两边字符串中间的空格放到后面地址

U2: MOV CX,CNT4

REP MOVSB

;把右边字符串放到空格后面

MOV CX,CNT5

JCXZ U3

MOV AL,20H

REP STOSB

U3:

SHOW: MOV ES,BP

MOV AH,0AH

MOV SI,1000H

MOV DI,LEFT

MOV CX,60-2

PPP: LODSB

STOSW

LOOP PPP

CALL DELAY

CMP CNT3,0

JZ @INPUT

INC CNT1

INC CNT5

DEC CNT3

CMP CNT3,0

JZ KK2

DEC CNT3

KK2: JMP Y3

;将es段的地址设置为0b800h,left为要显示字符的起始位置,把数据段1000h后面的数据转移到es段的相应位置即完成显示,没显示一次后cnt1加1,cnt5加1cnt3减2cnt135的意思见上面

@INPUT: MOV AH,0

INT 16H

CMP AH,10H ;'Q'

JZ SSS

CMP AH,13H ;'R'

JNZ @INPUT

CMP CNT3,0

JNZ @REP

JMP @Y2

@REP: JMP Y3

SSS: MOV STR+1,0

;这个很简单完成后用户输入Q退出,输入R继续

QUIT: LEA SI,CNT1

XOR AX,AX

MOV CX,5

KK3: MOV [SI],AX

INC SI

INC SI

LOOP KK3

XOR DI,DI

MOV CX,8025

MOV AX,720H

REP STOSW

RET

退出。

排序算法全集附C++代码

排序算法是一种基本并且常用的算法。由于实际工作中处理的数量巨大,所以排序算法对算法本身的速度要求很高。而一般我们所谓的算法的性能主要是指算法的复杂度,一般用O方法来表示。在后面我将给出详细的说明。

对于排序的算法我想先做一点简单的介绍,也是给这篇文章理一个提纲。

我将按照算法的复杂度,从简单到难来分析算法。

第一部分是简单排序算法,后面你将看到他们的共同点是算法复杂度为O(N*N)(因为没有使用word,所以无法打出上标和下标)。

第二部分是高级排序算法,复杂度为O(Log2(N))。这里我们只介绍一种算法。另外还有几种算法因为涉及树与堆的概念,所以这里不于讨论。

第三部分类似动脑筋。这里的两种算法并不是最好的(甚至有最慢的),但是算法本身比较奇特,值得参考(编程的角度)。同时也可以让我们从另外的角度来认识这个问题。

第四部分是我送给大家的一个餐后的甜点——一个基于模板的通用快速排序。由于是模板函数可以对任何数据类型排序(抱歉,里面使用了一些论坛专家的呢称)。

现在,让我们开始吧:

一、简单排序算法

由于程序比较简单,所以没有加什么注释。所有的程序都给出了完整的运行代码,并在我的VC环境

下运行通过。因为没有涉及MFC和WINDOWS的内容,所以在BORLAND C++的平台上应该也不会有什么

问题的。在代码的后面给出了运行过程示意,希望对理解有帮助。

1冒泡法:

这是最原始,也是众所周知的最慢的算法了。他的名字的由来因为它的工作看来象是冒泡:

#include <iostreamh>

void BubbleSort(int* pData,int Count)

{

int iTemp;

for(int i=1;i<Count;i++)

{

for(int j=Count-1;j>=i;j--)

{

if(pData[j]<pData[j-1])

{

iTemp = pData[j-1];

pData[j-1] = pData[j];

pData[j] = iTemp;

}

}

}

}

void main()

{

int data[] = {10,9,8,7,6,5,4};

BubbleSort(data,7);

for (int i=0;i<7;i++)

cout<<data<<” ”;

cout<<”\n”;

}

倒序(最糟情况)

第一轮:10,9,8,7->10,9,7,8->10,7,9,8->7,10,9,8(交换3次)

第二轮:7,10,9,8->7,10,8,9->7,8,10,9(交换2次)

第一轮:7,8,10,9->7,8,9,10(交换1次)

循环次数:6次

交换次数:6次

其他:

第一轮:8,10,7,9->8,10,7,9->8,7,10,9->7,8,10,9(交换2次)

第二轮:7,8,10,9->7,8,10,9->7,8,10,9(交换0次)

第一轮:7,8,10,9->7,8,9,10(交换1次)

循环次数:6次

交换次数:3次

上面我们给出了程序段,现在我们分析它:这里,影响我们算法性能的主要部分是循环和交换,

显然,次数越多,性能就越差。从上面的程序我们可以看出循环的次数是固定的,为1+2++n-1。

写成公式就是1/2*(n-1)*n。

现在注意,我们给出O方法的定义:

若存在一常量K和起点n0,使当n>=n0时,有f(n)<=K*g(n),则f(n) = O(g(n))。(呵呵,不要说没

学好数学呀,对于编程数学是非常重要的!!!)

现在我们来看1/2*(n-1)*n,当K=1/2,n0=1,g(n)=n*n时,1/2*(n-1)*n<=1/2*n*n=K*g(n)。所以f(n)

=O(g(n))=O(n*n)。所以我们程序循环的复杂度为O(n*n)。

再看交换。从程序后面所跟的表可以看到,两种情况的循环相同,交换不同。其实交换本身同数据源的

有序程度有极大的关系,当数据处于倒序的情况时,交换次数同循环一样(每次循环判断都会交换),

复杂度为O(n*n)。当数据为正序,将不会有交换。复杂度为O(0)。乱序时处于中间状态。正是由于这样的

原因,我们通常都是通过循环次数来对比算法。

2交换法:

交换法的程序最清晰简单,每次用当前的元素一一的同其后的元素比较并交换。

#include <iostreamh>

void ExchangeSort(int* pData,int Count)

{

int iTemp;

for(int i=0;i<Count-1;i++)

{

for(int j=i+1;j<Count;j++)

{

if(pData[j]<pData)

{

iTemp = pData;

pData = pData[j];

pData[j] = iTemp;

}

}

}

}

void main()

{

int data[] = {10,9,8,7,6,5,4};

ExchangeSort(data,7);

for (int i=0;i<7;i++)

cout<<data<<” ”;

cout<<”\n”;

}

倒序(最糟情况)

第一轮:10,9,8,7->9,10,8,7->8,10,9,7->7,10,9,8(交换3次)

第二轮:7,10,9,8->7,9,10,8->7,8,10,9(交换2次)

第一轮:7,8,10,9->7,8,9,10(交换1次)

循环次数:6次

交换次数:6次

其他:

第一轮:8,10,7,9->8,10,7,9->7,10,8,9->7,10,8,9(交换1次)

第二轮:7,10,8,9->7,8,10,9->7,8,10,9(交换1次)

第一轮:7,8,10,9->7,8,9,10(交换1次)

循环次数:6次

交换次数:3次

从运行的表格来看,交换几乎和冒泡一样糟。事实确实如此。循环次数和冒泡一样

也是1/2*(n-1)*n,所以算法的复杂度仍然是O(n*n)。由于我们无法给出所有的情况,所以

只能直接告诉大家他们在交换上面也是一样的糟糕(在某些情况下稍好,在某些情况下稍差)。

3选择法:

现在我们终于可以看到一点希望:选择法,这种方法提高了一点性能(某些情况下)

这种方法类似我们人为的排序习惯:从数据中选择最小的同第一个值交换,在从省下的部分中

选择最小的与第二个交换,这样往复下去。

#include <iostreamh>

void SelectSort(int* pData,int Count)

{

int iTemp;

int iPos;

for(int i=0;i<Count-1;i++)

{

iTemp = pData;

iPos = i;

for(int j=i+1;j<Count;j++)

{

if(pData[j]<iTemp)

{

iTemp = pData[j];

iPos = j;

}

}

pData[iPos] = pData;

pData = iTemp;

}

}

void main()

{

int data[] = {10,9,8,7,6,5,4};

SelectSort(data,7);

for (int i=0;i<7;i++)

cout<<data<<” ”;

cout<<”\n”;

}

倒序(最糟情况)

第一轮:10,9,8,7->(iTemp=9)10,9,8,7->(iTemp=8)10,9,8,7->(iTemp=7)7,9,8,10(交换1次)

第二轮:7,9,8,10->7,9,8,10(iTemp=8)->(iTemp=8)7,8,9,10(交换1次)

第一轮:7,8,9,10->(iTemp=9)7,8,9,10(交换0次)

循环次数:6次

交换次数:2次

其他:

第一轮:8,10,7,9->(iTemp=8)8,10,7,9->(iTemp=7)8,10,7,9->(iTemp=7)7,10,8,9(交换1次)

第二轮:7,10,8,9->(iTemp=8)7,10,8,9->(iTemp=8)7,8,10,9(交换1次)

第一轮:7,8,10,9->(iTemp=9)7,8,9,10(交换1次)

循环次数:6次

交换次数:3次

遗憾的是算法需要的循环次数依然是1/2*(n-1)*n。所以算法复杂度为O(n*n)。

我们来看他的交换。由于每次外层循环只产生一次交换(只有一个最小值)。所以f(n)<=n

所以我们有f(n)=O(n)。所以,在数据较乱的时候,可以减少一定的交换次数。

4插入法:

插入法较为复杂,它的基本工作原理是抽出牌,在前面的牌中寻找相应的位置插入,然后继续下一张

#include <iostreamh>

void InsertSort(int* pData,int Count)

{

int iTemp;

int iPos;

for(int i=1;i<Count;i++)

{

iTemp = pData;

iPos = i-1;

while((iPos>=0) && (iTemp<pData[iPos]))

{

pData[iPos+1] = pData[iPos];

iPos--;

}

pData[iPos+1] = iTemp;

}

}

void main()

{

int data[] = {10,9,8,7,6,5,4};

InsertSort(data,7);

for (int i=0;i<7;i++)

cout<<data<<” ”;

cout<<”\n”;

}

倒序(最糟情况)

第一轮:10,9,8,7->9,10,8,7(交换1次)(循环1次)

第二轮:9,10,8,7->8,9,10,7(交换1次)(循环2次)

第一轮:8,9,10,7->7,8,9,10(交换1次)(循环3次)

循环次数:6次

交换次数:3次

其他:

第一轮:8,10,7,9->8,10,7,9(交换0次)(循环1次)

第二轮:8,10,7,9->7,8,10,9(交换1次)(循环2次)

第一轮:7,8,10,9->7,8,9,10(交换1次)(循环1次)

循环次数:4次

交换次数:2次

上面结尾的行为分析事实上造成了一种假象,让我们认为这种算法是简单算法中最好的,其实不是,

因为其循环次数虽然并不固定,我们仍可以使用O方法。从上面的结果可以看出,循环的次数f(n)<=

1/2*n*(n-1)<=1/2*n*n。所以其复杂度仍为O(n*n)(这里说明一下,其实如果不是为了展示这些简单

排序的不同,交换次数仍然可以这样推导)。现在看交换,从外观上看,交换次数是O(n)(推导类似

选择法),但我们每次要进行与内层循环相同次数的‘=’ *** 作。正常的一次交换我们需要三次‘=’

而这里显然多了一些,所以我们浪费了时间。

最终,我个人认为,在简单排序算法中,选择法是最好的。

二、高级排序算法:

高级排序算法中我们将只介绍这一种,同时也是目前我所知道(我看过的资料中)的最快的。

它的工作看起来仍然象一个二叉树。首先我们选择一个中间值middle程序中我们使用数组中间值,然后

把比它小的放在左边,大的放在右边(具体的实现是从两边找,找到一对后交换)。然后对两边分别使

用这个过程(最容易的方法——递归)。

1快速排序:

#include <iostreamh>

void run(int* pData,int left,int right)

{

int i,j;

int middle,iTemp;

i = left;

j = right;

middle = pData[(left+right)/2]; //求中间值

do{

while((pData<middle) && (i<right))//从左扫描大于中值的数

i++;

while((pData[j]>middle) && (j>left))//从右扫描大于中值的数

j--;

if(i<=j)//找到了一对值

{

//交换

iTemp = pData;

pData = pData[j];

pData[j] = iTemp;

i++;

j--;

}

}while(i<=j);//如果两边扫描的下标交错,就停止(完成一次)

//当左边部分有值(left<j),递归左半边

if(left<j)

run(pData,left,j);

//当右边部分有值(right>i),递归右半边

if(right>i)

run(pData,i,right);

}

void QuickSort(int* pData,int Count)

{

run(pData,0,Count-1);

}

void main()

{

int data[] = {10,9,8,7,6,5,4};

QuickSort(data,7);

for (int i=0;i<7;i++)

cout<<data<<” ”;

cout<<”\n”;

}

这里我没有给出行为的分析,因为这个很简单,我们直接来分析算法:首先我们考虑最理想的情况

1数组的大小是2的幂,这样分下去始终可以被2整除。假设为2的k次方,即k=log2(n)。

2每次我们选择的值刚好是中间值,这样,数组才可以被等分。

第一层递归,循环n次,第二层循环2*(n/2)

所以共有n+2(n/2)+4(n/4)++n*(n/n) = n+n+n++n=k*n=log2(n)*n

所以算法复杂度为O(log2(n)*n)

其他的情况只会比这种情况差,最差的情况是每次选择到的middle都是最小值或最大值,那么他将变

成交换法(由于使用了递归,情况更糟)。但是你认为这种情况发生的几率有多大??呵呵,你完全

不必担心这个问题。实践证明,大多数的情况,快速排序总是最好的。

如果你担心这个问题,你可以使用堆排序,这是一种稳定的O(log2(n)*n)算法,但是通常情况下速度要慢

于快速排序(因为要重组堆)。

三、其他排序

1双向冒泡:

通常的冒泡是单向的,而这里是双向的,也就是说还要进行反向的工作。

代码看起来复杂,仔细理一下就明白了,是一个来回震荡的方式。

写这段代码的作者认为这样可以在冒泡的基础上减少一些交换(我不这么认为,也许我错了)。

反正我认为这是一段有趣的代码,值得一看。

#include <iostreamh>

void Bubble2Sort(int* pData,int Count)

{

int iTemp;

int left = 1;

int right =Count -1;

int t;

do

{

//正向的部分

for(int i=right;i>=left;i--)

{

if(pData<pData[i-1])

{

iTemp = pData;

pData = pData[i-1];

pData[i-1] = iTemp;

t = i;

}

}

left = t+1;

//反向的部分

for(i=left;i<right+1;i++)

{

if(pData<pData[i-1])

{

iTemp = pData;

pData = pData[i-1];

pData[i-1] = iTemp;

t = i;

}

}

right = t-1;

}while(left<=right);

}

void main()

{

int data[] = {10,9,8,7,6,5,4};

Bubble2Sort(data,7);

for (int i=0;i<7;i++)

cout<<data<<” ”;

cout<<”\n”;

}

2SHELL排序

这个排序非常复杂,看了程序就知道了。

首先需要一个递减的步长,这里我们使用的是9、5、3、1(最后的步长必须是1)。

工作原理是首先对相隔9-1个元素的所有内容排序,然后再使用同样的方法对相隔5-1个元素的排序

以次类推。

#include <iostreamh>

void ShellSort(int* pData,int Count)

{

int step[4];

step[0] = 9;

step[1] = 5;

step[2] = 3;

step[3] = 1;

int iTemp;

int k,s,w;

for(int i=0;i<4;i++)

{

k = step;

s = -k;

for(int j=k;j<Count;j++)

{

iTemp = pData[j];

w = j-k;//求上step个元素的下标

if(s ==0)

{

s = -k;

s++;

pData[s] = iTemp;

}

while((iTemp<pData[w]) && (w>=0) && (w<=Count))

{

pData[w+k] = pData[w];

w = w-k;

}

pData[w+k] = iTemp;

}

}

}

void main()

{

int data[] = {10,9,8,7,6,5,4,3,2,1,-10,-1};

ShellSort(data,12);

for (int i=0;i<12;i++)

cout<<data<<” ”;

cout<<”\n”;

}

呵呵,程序看起来有些头疼。不过也不是很难,把s==0的块去掉就轻松多了,这里是避免使用0

步长造成程序异常而写的代码。这个代码我认为很值得一看。

这个算法的得名是因为其发明者的名字DLSHELL。依照参考资料上的说法:“由于复杂的数学原因

避免使用2的幂次步长,它能降低算法效率。”另外算法的复杂度为n的12次幂。同样因为非常复杂并

“超出本书讨论范围”的原因(我也不知道过程),我们只有结果了。

四、基于模板的通用排序:

这个程序我想就没有分析的必要了,大家看一下就可以了。不明白可以在论坛上问。

MyDatah文件

///////////////////////////////////////////////////////

class CMyData

{

public:

CMyData(int Index,char* strData);

CMyData();

virtual ~CMyData();

int m_iIndex;

int GetDataSize(){ return m_iDataSize; };

const char* GetData(){ return m_strDatamember; };

//这里重载了 *** 作符:

CMyData& operator =(CMyData &SrcData);

bool operator <(CMyData& data );

bool operator >(CMyData& data );

private:

char* m_strDatamember;

int m_iDataSize;

};

////////////////////////////////////////////////////////

MyDatacpp文件

////////////////////////////////////////////////////////

CMyData::CMyData():

m_iIndex(0),

m_iDataSize(0),

m_strDatamember(NULL)

{

}

CMyData::~CMyData()

{

if(m_strDatamember != NULL)

delete[] m_strDatamember;

m_strDatamember = NULL;

}

CMyData::CMyData(int Index,char* strData):

m_iIndex(Index),

m_iDataSize(0),

m_strDatamember(NULL)

{

m_iDataSize = strlen(strData);

m_strDatamember = new char[m_iDataSize+1];

strcpy(m_strDatamember,strData);

}

CMyData& CMyData::operator =(CMyData &SrcData)

{

m_iIndex = SrcDatam_iIndex;

m_iDataSize = SrcDataGetDataSize();

m_strDatamember = new char[m_iDataSize+1];

strcpy(m_strDatamember,SrcDataGetData());

return *this;

}

bool CMyData::operator <(CMyData& data )

{

return m_iIndex<datam_iIndex;

}

bool CMyData::operator >(CMyData& data )

{

return m_iIndex>datam_iIndex;

}

///////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////

//主程序部分

#include <iostreamh>

#include ”MyDatah”

template <class T>

void run(T* pData,int left,int right)

{

int i,j;

T middle,iTemp;

i = left;

j = right;

//下面的比较都调用我们重载的 *** 作符函数

middle = pData[(left+right)/2]; //求中间值

do{

while((pData<middle) && (i<right))//从左扫描大于中值的数

i++;

while((pData[j]>middle) && (j>left))//从右扫描大于中值的数

j--;

if(i<=j)//找到了一对值

{

//交换

iTemp = pData;

pData = pData[j];

pData[j] = iTemp;

i++;

j--;

}

}while(i<=j);//如果两边扫描的下标交错,就停止(完成一次)

//当左边部分有值(left<j),递归左半边

if(left<j)

run(pData,left,j);

//当右边部分有值(right>i),递归右半边

if(right>i)

run(pData,i,right);

}

template <class T>

void QuickSort(T* pData,int Count)

{

run(pData,0,Count-1);

}

void main()

{

CMyData data[] = {

CMyData(8,”xulion”),

CMyData(7,”sanzoo”),

CMyData(6,”wangjun”),

CMyData(5,”VCKBASE”),

CMyData(4,”jacky2000”),

CMyData(3,”cwally”),

CMyData(2,”VCUSER”),

CMyData(1,”isdong”)

};

QuickSort(data,8);

for (int i=0;i<8;i++)

cout<<datam_iIndex<<” ”<<dataGetData()<<”\n”;

cout<<”\n”;

要真想成为高手,要相当的一部分时间,首先是楼上说的汇编。对于初学者来说,软件不是那么好破的。给你的建议,先学汇编,然后去看《加密解密》现在这本书出第三版,是看雪(>

先求出 bunpu数组中的最大值maxr,以此值为初值递减循环至1,凡数组值与循环变量相等则输出

int maxr=bunpu[0];

for(i = 1; i < 11;++i)

{ if(bunpu[i]>maxr)maxr=bunpu[i];}

for(i=maxr;i>0;--i)

{

for(j=0;j<11;++j){

if(bunpu[j]<=i)

printf("%4c",'');

}

printf("\n");

}

1 引言

11 编写目的:编写此文档的目的是进一步定制软件开发的细节问题,便于用户与开发商协调工作本文档面向的读者主要是项目委托单位的管理人员希望能使本软件开发工作更具体

12 项目背景

121项目委托单位:公司

122开发单位:公司

13 定义

14参考资料

2 任务概述

21 目标:

决策支持:根据公司的要求及时提供所需报表及文件,并在适当时候对各部门领导给予销售及进货等方面的提示

提高效率:利用软件进行管理,避免人工管理的失误以及 延迟性,从而实现高效率的管理

22 运行环境:

硬件方面:Pentium级处理芯片

1兆显存的兼容显卡

256色,800600的兼容显示器

标准兼容打印机

软件方面: WIN95 *** 作系统

23 条件与限制:

编程用计算机一台

完成期限2000/7/1

无资金供给

3 数据概述

数据流程图如下:

31 静态数据:包括系统登录密码,各数据库所在位置,系统分析原始数据

32动态数据:包括各数据库内各项显示数据,用户登录信息,系统时间

33 数据库描述:

人事管理数据库:公司内人员的个人详细信息,包括档案信息

销售管理数据库:当日销售记录及以前的销售统计,用于销售分析

财务管理数据库:公司内部账目及收支情况详表

技术管理数据库:公司所需各技术档案的详细记录(包括文档)

34 数据字典:

数据流词条描述:

1数据流名:登录信息

来源:用户的输入

去向:系统内部检验部分

组成:用户名,密码

流通量:每次登录输入一次

2数据流名:登录结果

来源:系统

去向:用户

组成:返回信息

流通量:每次登录返回一次

3数据流名:输入修改信息

来源:用户

去向:系统判断部分

组成:根据各数据库内容而不同

流通量:依用户输入而定

4数据流名:反馈信息

来源:系统判断部分

去向:用户

组成:系统经判断后发回的字符数据

流通量: 依系统当前信息而定

5数据流名:识别信息

来源:系统内部检验部分

去向:系统判断部分

组成:系统各数据库的标识信息

流通量:用户每次输入流通一次

6数据流名:处理信息

来源:系统判断部分

去向:各数据库处理部分

组成:读取/修改标识,读取/修改的变量名称

流通量:用户每次输入流通一次

7数据流名:读取修改

来源:系统判断部分

去向:系统各数据库

组成:读取/修改标识,读取/修改内容

流通量: 用户每次输入流通一次

数据文件词条描述:

1数据文件名:人事数据

简述:存储人员信息

数据文件组成:人员的各项信息(以CString类型为主)

2数据文件名:销售数据

简述:存储当日及从前的销售记录

数据文件组成:销售的各项信息

3数据文件名:财务数据

简述:存储财务管理信息

数据文件组成:财务管理的各项记录

4数据文件名:技术数据

简述:存储公司内部使用的技术档案信息

数据文件组成:技术档案名称,内容

加工逻辑词条描述:

1加工名:检验

简要描述:判断用户的许可性

输入数据流:登录信息

输出数据流:登录结果

加工逻辑:判断是否与系统内部用户信息相符合

2加工名:判断

简要描述:判断用户的 *** 作并进行相应的读取/存储工作

输入数据流:输入修改信息

输出数据流:反馈信息

加工逻辑:判断用户的 *** 作->调用数据库->读取/修改->反馈

3加工名:人事档案管理

简要描述:对人事数据库进行相应要求的 *** 作,并与判断部分交互

输入数据流:处理信息,读取修改

输出数据流: 读取修改, 处理信息

加工逻辑:判断用户要读取/修改的内容->反馈用户所需信息

4加工名:销售统计

简要描述:对销售数据库进行相应要求的 *** 作,并与判断部分交互

输入数据流:处理信息,读取修改

输出数据流: 读取修改, 处理信息

加工逻辑:判断用户要读取/修改的内容->反馈用户所需信息

5加工名:财务统计

简要描述:对财务数据库进行相应要求的 *** 作,并与判断部分交互

输入数据流:处理信息,读取修改

输出数据流: 读取修改, 处理信息

加工逻辑:判断用户要读取/修改的内容->反馈用户所需信息

6加工名:技术管理

简要描述:对技术统计数据库进行相应要求的 *** 作,并与判断部分交互信息

输入数据流:处理信息,读取修改

输出数据流: 读取修改, 处理信息

加工逻辑:判断用户要读取/修改的内容->反馈用户所需信息

源点及汇点词条描述:

名称:用户

简要描述:既是源点又是汇点,发出动作信息给"检验"和"判断"加工,通过交互界面接受反馈信息有关数据流:登录结果,登录信息,输入修改信息,反馈信息

数目:一个

4 功能需求

41 功能划分

可细分为四部分:人事管理,销售管理,财务管理,技术档案管理

42 功能描述

人事功能:

(1)能对公司内部的所有人员有关档案详细资料记录并保存。

(2)能对数据库内人事档案的数据进行查阅和修改。

(3)能按部门或姓名检索人员。

(4)当某员工的雇用期限达到整年时,按时提醒。

销售统计功能

(1)按日对公司的销售情况进行统计,包括销售额\销售数量\各地区销售比例\不同销售方式的销售量比例以及销售毛利润情况

(2)制定销售情况的月报表\季报表以及年报表对销售情况进行分析,对不同销售人员的业绩进行评定

财务管理功能

(1)协助财务人员进行计算机管理,对库存情况\进货情况\销货进行登录和输出

(2) 根据预设的库存情况提醒进货

(3) 对收款情况进行统计,在应收帐款达到预设值时进行提示

技术管理功能

(1)对技术资料进行登录

(2)对维修记录进行登录和统计,按不同型号的机器进行故障整体分析,并作出分析报告

(3)对维修配件的需求进行管理并及时提示备货

5 性能需求

51 数据精确度:因为此数据为公司内部数据,所以要求不能有误差

52 时间特性:当日销售统计要求有即时性,马上能反应出存货的问题;同时财务管理数据计算当前存货情况,并对进货情况进行估算

53适应性:此软件只在公司内部管理人员的机器上使用,因此不考虑适应性

6 运行需求

61 用户界面:

屏幕格式:

(1)要求有菜单及工具栏以方便 *** 作

(2)各数据库信息可在屏幕上直接修改

(3)各数据统计结果可在屏幕上显示

(4)进行系统分析后的结果在另一窗口中显示

报表格式:

(1)人事管理报表只要求有个人的普通数据

(2)销售统计报表要求可分别打印当日统计或之前的统计

(3)财务统计报表要求打印出存货及公司帐务详表

(4)技术管理报表要求可以分别打印技术档案总表和任一技术档案文档内容菜单格式:要求菜单项大致与WIN95标准相同,另外附加的功能做到新的单项中输入输出时间:年份以4位数字表示

62 硬件接口:需要标准打印机接口进行报表打印

63软件接口:Windows标准接口

7 其他需求

可使用性:要求容易使用,界面友好

安全保密性:因本数据属于公司内部管理用关键数据,因此除公司管理人员外,其他人员不得访问要求设有登录密码检验功能,并且此密码可以在以后进行修改

可维护性:要求本软件的维护文档齐全,便于维护

以上就是关于C语言程序分析全部的内容,包括:C语言程序分析、帮忙分析一下这个程序的含义,做的工作是什么,求写出每行详细的注释、急求排序算法性能分析程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9704876.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存