Download - Trainee Material
-
7/31/2019 Trainee Material
1/40
Table of Contents
1. Basic Instruction ........................... 2
2. Code Standards ........................... 3
3. C Compiler Preprocessors ........................... 5
4. Dynamic Memory Allocation ........................... 7
5. About typedef ........................... 8
6. If-Else and its Alternatives ........................... 9
7. Structural Arrangements ........................... 14
8. Container Concept ........................... 169. How to Use VOID pointer ........................... 18
10. About Offset ........................... 20
11. Array of Pointer ........................... 21
12. About Segmentation Fault ........................... 24
13. How to make Domain Application ........................... 29
13.1. About Event ........................... 29
13.2. Structure Construction ........................... 30
13.3. Signature Construction ........................... 36
13.4. Sample Code for Signature .......................... 37
-
7/31/2019 Trainee Material
2/40
Basic Instruction
*modularize the code.
*Use datatype as NODE for structure pointer avaiable inside the structures
The NODE is nothing but the datatype of void
typedef void NODE;
*If possible use generic pointer(void*) to write common functions,so thatwe can call the function without respect to its pointer type, And we can
retrive the data by typecast.
*Declarations should be at the top of the function, not in execution part of
the program.
*Memory allocated using malloc or calloc should be freed if it is not
not used anywhere.
*One must not free or use the chunk of memory which is already freed using
free function.It 'll raise segmentation fault.
*free function must be called to free the chunk of memory which is
created either by malloc or by calloc function.*Here we should Use linkedList to persist Data as of now.
Createing Directory
Syntax : $ mkdir FolderName
Example : $ mkdir Protech
Change to forward(fwd) Directory : $ cd folderNameChange to backward(bwd) Directory : $ cd ..
Some Commands for related Directory
Change to bwd More than 1 directory : $ cd ../../../
: $ cd ../FolderName
: $ cd FolderName/SubFolder
Createing File
Syntax : $ vi FileName.Extension
Example : $ vi Source.c
Compiling C source code:
gcc main.c (to create binary file(a.out))
gcc -c main.c (to create object file)
Vi Editor shortcuts:
V= to select a line. Press up or down arrows to select more lines.
Y= to copy the selected line(s).
p= to paste next to the current line.
Note:
Here the motto is, The code should be simple and efficient
The structures designing for Domain(like OMS,HMS,Reseller,Auditor,etc..,)
should be less memory consuming and accessing time for the data should be less.
-
7/31/2019 Trainee Material
3/40
P= to paste Previous to the current line.
u= to undo the changes.
Ctrl+r= to redo the undone action.
Code Standards:
Our Organization has some basic formats for codings. This should be uniqueand every one should Follow this. They are given below,
In variable declaration, A variable name should contains the Prefix of the
date type declared. That is a variable name should tell that what date type
is this. For example:
int iRollNo; // integer variable
float fAmount; // float variable
char cSex; // character variable
ADDRESS oPermanentAddress; // object variable
ADDRESS *pTemporaryAddress; // pointer variable
If there is more than one word in a variable name, then each first letter of
the each word should be in Capital. For example,
Roll no ---> RollNo
Permanent address ---> PermanentAddress
Temporary address ---> TemporaryAddress
Give proper name to the variables. Using the name itself, we can
understand the role of that variable.
All Function prototype and construct the structures in Header file(*.h) notin source file(*.c).Include that header file in your source file If required.
Minimal usage of temporary variables used in a function.Mostly avoid
temporary variables inside functions.
For Functions, Function name tells that whats is going to do.If there is
more than one word in a function name, then each first letter of the each
word should be in Capital
Each Function should be written in a separate file. The filename should be
the function name.
When writing a function, think and make it as a common function. Its
useful for other domains also.
To make a common function, instead of using the structure parameter use
offsets. Its useful for other structure functions also.
-
7/31/2019 Trainee Material
4/40
Avoid the use of if-else statements in a function. Use logical operators and
bitwise operators in a function.Instead of if-else probably Function
Pointers and Array of pointers can be used for efficiency.
A function should be written in Efficient and simple manner.
For example, strcpy() function
int strcpy(char *cSource, char *cDestination)
{
while(*cDestination != '\0')
{
*cSource = *cDestination;
cSource = cSource + 1;
cDestination = cDestination + 1;
}}
The above function is rewritten in a efficient and simple manner like this,
int strcpy(char *cSource, char *cDestination)
{
while(*cSource++ = *cDestination++) ;
}
The defined Macros should be in Uppercase.
Each function should be of Return type as int .Because to reporting error
in the funtion.You have to construct function such that if the function
return 0 means non-Error . Returns non-Zero means Error.So that
communicate with one function to other function.
Proper Error handling must be for each function. Example : NULL should
be checked for nullable variables.
Use Conditional Inclusion in the Header files.
Use -Wall while compilation to show all warnings.eg. $ gcc main.c foo.c -Wall
Input And Output codes should have separate files. Should not mingle
with any other function codes.
-
7/31/2019 Trainee Material
5/40
C compiler preprocessors
Preprocessor commands are executed before the compiler compiles the
source code. These commands will change the original code usually to suit the operating
environment and/or to add code that will be required by calls to library functions.
Preprocessors are recognised by the leading # in their names.
Include preprocessor
The include preprocessor will add source code to your existing source. This
is used to include header files that contain function declarations.
* '< >' says to the preprocessor that the file is in the system libraries.
Example: #include
* means that this is a user defined file. Absolute or relative paths may be
defined. Example: #include "myheaders.h"
#include "/usr/home/leslim/myheaders.h"
#define preproces
The#define preprocessor allows us to define symbolic names and constants.
A quick example
#define PI 3.14159
This statement will translate every occurance of PI in the program to
3.14159. Here is a more complete example:
#define PI 3.14159
main(){
int r=10; float cir;
cir = PI * (r*r);
}
-
7/31/2019 Trainee Material
6/40
Conditional Inclusion
Use Conditional Inclusion at the time of header file include. The #if lines
evaluates a constant integer expression (which may not include sizeof, casts or enum
constants). If the expression is non-zero, subsequent lines until an #endif or #elif or #else
are included. (The preprocessor statement #elif is like else if ). The expressiondefined(name) in a #if is 1 if the has been defined, and 0 otherwise.
Example:
#ifndef _HMSHeader_
#define _HMSHeader_
/* HMS Structures */
typedef struct Container
{
void *pNext;void *pDataPtr;
}CONTAINER;
typedef struct Todo
{
int iEntryDate;
int iTodoTask;
int iDueDate;
int iDueTime;
char cPriority; // 0-Low,1-Medium, 2-High
int iNotes;}TODO;
/* All structures will com here */
#endif
-
7/31/2019 Trainee Material
7/40
Dynamic Memory Allocate
Malloc (memory allocation) is used to dynamically allocate memory at run
time. Possible uses for this function are
Read records of an unknown length.
Read an unknown number of database records.
Link lists.
The simplest way to reserve memory is to code something like
The example above has two problems
1) If the data is less than 1000 bytes we are wasting memory.
2) If the data is greater than 1000 bytes the program is going to crash.
3) The 1000 bytes are reserved throught out the life of the program. If this
was a long running program that rarely used the memory, it would again be wasteful
malloc allows us to allocate exactly the correct amount of memory and with
the use of free only for the time it is required.
Malloc return type is void Pointer thats we use typecast.
Calloc (memory allocation) allocates memory for an array of nmemb
elements of size bytes each and returns a pointer to the allocated memory. The memory is
set to zero
Library: stdlib.h
Prototype: void *malloc(size_t size);
Syntax: char * String; String = (char *) malloc(1000);
Main()
{
char string[1000];
strcpy(string, "Some text");
}
Syntax:
#include
void *calloc(size_t nmemb, size_t size);
-
7/31/2019 Trainee Material
8/40
Typedef
Every variable has a data type. typedef is used to define new data type
names to make a program more readable to the programmer.
These examples are EXACTLY the same to the compiler. But the right hand
example tells the programmer the type of money he is dealing with.
Some Other type of Typedef:
1) typedef enum {FALSE=0, TRUE} Boolean
main () {
Boolean flag = TRUE;
}
2) typedef char *String;
main() {
String Text = "Thunderbird";
printf("%s\n", Text);
}
3) typedef struct {
int age;
char *name
} person;
person people;
As a final note, you can create several data types in one hit.
typedef int Pounds, Shillings, Pennies, Dollars, Cents;
Main(){
int Money;
Money=20;
}
Main(){
typedef int Pounds;
Pounds Money=20;
}
-
7/31/2019 Trainee Material
9/40
If Else
We want check something in our Program means to use If else. Suppose
we check more than one data,in that time the Occurance ofifis more.So Our coding will
be more lenghy and Not Effective way of Program.We should follow the below
standards.
Scenario - I From HMS:
In Home Management System, To-Do Module is used to write the things we
want to do. To add a new to-do User has to enter the to-do contents ( pick up laundry,
buy flowers, pickup dad from airport etc ) and due date and time. This due date and time
is a future date and time only. If date is current date, then time should be a future one.
Screen for ToDo Module in HMS
Int IsGreater(int iFirst, int iSecond)
{
if(iFirst > iSecond)
return 1;
else
return 0;
}
int IsGreater(int iFirst, int iSecond)
{
return (iFirst > iSecond);
}
Normal way of If-Else Our Standards If-Else
-
7/31/2019 Trainee Material
10/40
Wrong Way of Apporach
HMS To-Do Structure
typedef struct Todo
{
int iEntryDate;
int iTodoTask;int iDueDate;
int iDueTime;
char cPriority; // 0-Low, 1-Medium, 2-High
int iNotes;
}TODO;
Int RunCreateTODO(HMS *HMSRoot, TODO *Todo)
{ int i,j,date;
i=(IsCurrentDate(Todo->iDueDate));
if(i==-1) {
printf("Past Date:\n");
return 1;
}
GetCurrentDate(&date);
if(date==(Todo->iDueDate))
{
j=(IsCurrentTime(Todo->iDueTime));
if(jpTODO,(void*)Todo);
///* This function is used to add the node in List. */
return 0;
}
Tempory Variable
i,data,j
DrawBack
UnWanted Printf
I=(IsCurrentDate(Todo->iDueDate));
if(i==-1) { // Set of lines }
-
7/31/2019 Trainee Material
11/40
In Our Apporach
Scenario - II From HMS
There are many types of expenses we make in our day to day life. For
Record that Use Expense Module in HMS. We spend some money the expense should be
less than or equal to our Cash balance or Bank balance.
Expense Screen in HMS
int RunCreateTODO(HMS *HMSRoot, TODO *Todo)
{
int iDate;
return ((((iDate = IsCurrentDate(Todo->iDueDate))==-1) ||
((iDate==0) && (IsCurrentTime(Todo->iDueTime) < 1))) ||
AssignContainer((void **)&HMSRoot->pTODO, (void*)ToDo);
}
-
7/31/2019 Trainee Material
12/40
Sub Screen in Expense (Above Screen)
-
7/31/2019 Trainee Material
13/40
Wrong Way of Apporach
Our Apporach
int CheckExpenseAmountWithPaymentTypeAmount
(HMS *pHMSRoot, RECIPAYMENT *pPayment, void *pBankRef)
{
if(pPayment->cReceiptPaymentType == 0)
return CheckCashBalance(pHMSRoot,pPayment);
else if( pPayment->cReceiptPaymentType == 1)
return CheckBankBalance(pHMSRoot, pPayment,pBankRef );
}
int IsFloatValueSmallOrEqual(float fFirstAmt, float fSecondAmt)
{
return fFirstAmt > fSecondAmt ;
}
int CheckCashBalance(HMS *pHMSRoot, RECIPAYMENT *pPayment)
{
return IsFloatValueSmallOrEqual(pHMSRoot->fCashBalance,pPayment->fReceiptPaymentAmount);
}
int CheckExpenseAmountWithPaymentTypeAmount
(HMS *pHMSRoot, RECIPAYMENT *pPayment, void *pBankRef)
{
int (*FnPtrCheckCashBank[])(HMS*,RECIPAYMENT *,void*) =
{ CheckCashBalance, CheckBankBalance};
return (*FnPtrCheckCashBank[(int)pPayment-> cReceiptPaymentType])
(pHMSRoot,pPayment,pBankOrCardRef);
}
Become Like that
Using Function Pointer
-
7/31/2019 Trainee Material
14/40
Structural Arrangement
1.Reusablity
2.MemoryConception
3.Fast Access Data.
Normal Party Structure for all domain
ReUseable
Typedef struct PartyEntity{
int iPartyID;
int iName;
char cPartyType;
// Cus,Sup,Cus/Sup/Agency,If Party Config And TxnBank Config is same1bit
//char cBankConfigureStatus;
int iAsOnDate;
float fOpeningBalance;
float fCurrentBalance;
float fOverallRankOfParty;
int iPaymentOrReceiptCount[2];
int iInstrumentLastDate[7][3];
void *pPartyItemDetails; //Arranged acc to Items best response
float fDueAmount;
int iTotalTransactionCount;
int iBankTxnCount;
int iCashTxnCount;
float fAverageInstrumentAmount[2];
int iAddressLine1;
int iAddressLine2;
int iArea;
int iContactNo;int iFAXNo;
int iEMailID;//abc_xyz
int iEMailAddress;//@gmail.com
int iPANNo;
int iLicenseNo;//CST No
NODE *pLocation;//DIRECT LocationConfig(City,State,Country)
int iPinCode;
};
-
7/31/2019 Trainee Material
15/40
Same PartyEntity But Break Address
In the above example we Break the address Node.Because in the kind ofNode to needed for all domain.Suppose its no Need means to put NULL.Null is Nothing
but 0.
If suppose one scenario To show all payment for Specfic Customer so
we kept the Payment Reference to Customer also.
CONTAINER *pPayment;
Typedef struct PartyEntity
{
int iPartyID;int iName;
char cPartyType;
// Cus,Sup,Cus/Sup/Agency,If Party Config And TxnBank Config is same1bit
//char cBankConfigureStatus;
int iAsOnDate;
float fOpeningBalance;
float fCurrentBalance;
float fOverallRankOfParty;
int iPaymentOrReceiptCount[2];
int iInstrumentLastDate[7][3];
void *pPartyItemDetails; //Arranged acc to Items best response
float fDueAmount;
int iTotalTransactionCount;
int iBankTxnCount;int iCashTxnCount;
float fAverageInstrumentAmount[2];
container *pAddress;
};
typedef struct Address
{
int iAddressLine1;
int iAddressLine2;
int iArea;
int iContactNo;
int iFAXNo;
int iEMailID;//abc_xyz
int iEMailAddress;//@gmail.com
int iPANNo;
int iLicenseNo;//CST No
NODE *pLocation;//DIRECT LocationConfig(City,State,Country)
int iPinCode;
}ADDRESS;
-
7/31/2019 Trainee Material
16/40
Screen for SUGAR
We entered data and click the Add Button, above all details will be store in
the Below corresponding Struct Variables its become a NODE.
After that we keep that data in our Memory so, use some DataStructure
like LinkedList,Tree,Array etc.,Here we use linked list but structural arrangement is
different.That Concept Name is CONTAINER.
CONTAINER Concept
Container is nothing but the wrapper that is List.Its have
1.DataPointer
2. Next Node Address
Typedef struct OtherIndustriesConfig{
int iItemCode;
int iItemName;
int iDistance;
int iDescription;
Node *pLocation;
}OTHERINDUSTRIESCONFIG;
-
7/31/2019 Trainee Material
17/40
Here DataPointer is nothing but OtherIndustriesConfig Structure.Before
fill data we allocate the memory for that.
Now we make or Append that node to CONTAINER.So we make the
Container Node first
Make a Container for recently get Node.
Struct Container *pNext; ==>NULL
Struct
PotherIndustriesConfig
Address=>2004
Address=>1000
Container Node
OTHERINDUSTRIESCONFIG *pOtherIndustriesConfig;pOtherIndustriesConfig =
(OTHERINDUSTRIESCONFIG*)malloc(sizeof(OTHERINDUSTRIESCONFIG))
Typedef struct Container
{struct Container *pNext;
NODE *pDataPonter;
}
-
7/31/2019 Trainee Material
18/40
Insert in to Container List
How to Use VOID
Typedef struct Container
{
void *pNext;NODE *pDataPonter;
}CONTAINER;
CONTAINER *pRoot,*pTemp;
void *pRoot,*pTemp;
Root=pTemp->pNext
pRoot=(void **)*pTemp
Pnext
Void **pRoot,
*(int*)*pRoot
*(int*)(((int*)*root)+1)
DataPointer
Void *pRoot,
*(int*)pRoot
*(int*)(pRoot+4)
Container
Root->pDataPointer=
pTemp->pDataPointer
*(int*)(pRoot+4)=*(int*)(Temp+4)
pNext => 1008
DataPointer =>2010
pNext => 1012
DataPointer =>2020
pNext => NULL
DataPointer =>2030
1000 1008 1016
Int AssignContainer(CONTAINER **pRoot,NODE *pNode)
{
CONTAINER *pTempContainer=(CONTAINER *)malloc(8);
pTempContainer->pDataPointer=pNode;
pTempContainer->pNext =*pRoot;
*pRoot=pTempContainer;return 0;
}
-
7/31/2019 Trainee Material
19/40
Int AssignContainer(CONTAINER **pRoot,NODE *pNode)
{
CONTAINER *pTempContainer=(CONTAINER *)malloc(8);
pTempContainer->pDataPointer=pNode;pTempContainer->pNext =*pRoot;
*pRoot=pTempContainer;
return 0;
}
Example Code With Out Using Void
IitemCode
IitemName
Idistance
Idescription
1000
2000
1000
1004
1008
1012
Node
*pNode
*(pNode+0)
*(pNode+4)
*(pNode+8)
Void *Node;
Typedef struct OtherIndustriesConfig
{
int iItemCode;
int iItemName;int iDistance;
int iDescription;
}OTHERINDUSTRIESCONFIG;
OTHERINDUSTRIESCONFIG *pTemp;pTemp=
(OTHERINDUSTRIESCONFIG*)malloc(sizeof(OTHERINDUSTRIESCONFIG));
Node=pTemp;
Offset
-
7/31/2019 Trainee Material
20/40
Example Code With Using Void
Offset is a Number its increment by what we mention.
*(int *)(pTempContainer+4)
Here pTempContainer increment by 4. That 4 is Offset.Itsdiffer from datatype to datatype.
Pointer Arithmentic
Increment
DataType Size Size
Of *
Increment Sample Start
Address
Sample End
Address
Int* 4 4 + + 2000 2004Float* 4 4 + + 3000 3004
Char* 1 4 + + 1000 1001
Void* 1 4 + + 300 301
Structure* Sizeof
(Struct
ure) 4
+ +
300
300+Sizeof
(Structure)
Int AssignContainer (void **pRoot,void *pNode)
{
void *pTempContainer=(int *)calloc(1,8);*(int *)(pTempContainer+4)=(int )((int *)pNode);
(int *)*(int *)pTempContainer=(int*)*pRoot;
*pRoot=(int*)pTempContainer;
return 0;
}
Insert Node
Container Create
-
7/31/2019 Trainee Material
21/40
Decrements
DataType Size Size
Of *
Decrement Sample Start
Address
Sample End
Address
Int* 4 4 - - 2004 2000
Float* 4 4 - - 3004 3000
Char* 1 4 - - 1001 1000
Void* 1 4 - - 301 300
Structure* Sizeof
(Struct
ure) 4
- -
300
300-Sizeof
(Structure)
Array of Pointer
The way there can be an array of ints or an array of floats,similarly there
can be an array of pointers. Since a pointer variable always contains an address, an array
of pointers would be nothing but a collection of addresses. The addresses present in the
array of pointers can be addresses of isolated variables or addresses of array elements or
any other addresses. All rules that apply to an ordinary array apply to the array of
pointers as well. I think a program would clarify the concept.
In OMS(Office Mgmt System) have one scenario that is.,
The above Root is OMS Main Root.we want to insert a Node to any one SubRoot like (Enquiry,Quotation....) with respect to its type passed as its argument.There are
TWO way to insert
Typedef struct Oms{
CONTAINER *pEnquiry;
CONTAINER *pQuotation;
CONTAINER *pOrder;
CONTAINER *pDc;
CONTAINER *pInvoice;
CONTAINER *pGoodsReturn;
CONTAINER *pGRN;
}OMS;
-
7/31/2019 Trainee Material
22/40
Normal Way
The above case we can also switch case but it is also Inefficient.
DrawBack Of Above Coding
No.Of Lines More
More Checking
if... else if
Code Repeat in every if AssignContainer
int RunCreateAndInsertInstrument(OMS *pOMSRoot,Node *pInstrument,
int iInstrumentNo)
{
if(iInstumentNo==1)
{// Enquiry Instument
AssignContainer(&pOMSRoot->pEnquiry, Node *pInstrument );
}
else if(iInstumentNo==2)
{
// Qutation Instument
AssignContainer(&pOMSRoot->pQuotation, Node *pInstrument );
}
else if(iInstumentNo==3)
{
// Order Instument;
AssignContainer(&pOMSRoot->pOrder, Node *pInstrument );}
else if(iInstumentNo==4)
{
// DC Instument;
AssignContainer(&pOMSRoot->pDC, Node *pInstrument );
}
else if(iInstumentNo==5)
{
// Invoice Instument;
AssignContainer(pOMSRoot->pInvoice, Node *pInstrument );
}
else if(iInstumentNo==6){
// Goods Returns Instument;
AssignContainer(&pOMSRoot->pGoodReturns, Node *pInstrument );
}
else if(iInstumentNo==7)
{
// GRN Instument;
AssignContainer(&pOMSRoot->pGRN, Node *pInstrument );
}
}
-
7/31/2019 Trainee Material
23/40
we rectify the above drawbacks.Here we use Array of Pointers
Double Pointer
Int AssignContainer (void *pRoot,void *pNode)
{
void *pTempContainer=(int *)calloc(1,8);
*(int *)(pTempContainer+4)=(int )((int *)pNode);
*pRoot=InsertFirst(*pRoot,pNode);
return 0;
}
void *InsertFirst(void *pRoot,void *pNode){
(int *)*(int *)pNode=(int*)pRoot;pRoot=(int*)pNode;
return pRoot;
}
Int AssignContainer (void *pRoot,void *pNode)
{
void *pTempContainer=(int *)calloc(1,8);
*(int *)(pTempContainer+4)=(int )((int *)pNode);
InsertFirst(&pRoot,pNode);return 0;
}
void *InsertFirst(void **pRoot,void *pNode){
(int *)*(int *)pNode=(int*)*pRoot;
*pRoot=(int*)pNode;
}
int RunCreateAndInsertInstrument(OMS *pOMSRoot,Node *pInstrument,int iInstrumentNo)
{
Void *pInstrumentRoot[]={&pOMSRoot->pEnquiry,&pOMSRoot->pQuotation,
&pOMSRoot->pOrder,&pOMSRoot->pGRN,
&pOMSRoot->pDC,&pOMSRoot->pInvoice,
&pOMSRoot->pGoodsReturn};
AssignContainer(pInstrumentRoot[iInstrumentNo],pInstrument);
}
Return the Root
address
Return Type Void
Pointer
Address of Root
-
7/31/2019 Trainee Material
24/40
How to Avoid Segmentation Fault
Fault - I
#includetypedef struct Party
{
int iPartyId;
char *cPartyName;
}Party;
int main()
{
Party *pNewParty;
printf("Pointer Addr:\t%p\n",pNewParty);
printf("PartyId:\t[%d]\nPartyName:\t[%s]\n",
pNewParty->iPartyId,pNewParty->cPartyName);
return 0;
}
Output Screen
Its Garbage Value May be here
Segment fault will occure
-
7/31/2019 Trainee Material
25/40
Fault - II
#include
typedef struct Party
{
int iPartyId;
char *cPartyName;
}Party;
int main()
{
Party *pNewParty=NULL;
printf("Pointer Addr:\t%p\n",pNewParty);
printf("PartyId:\t[%d]\nPartyName:\t[%s]\n",
pNewParty->iPartyId,pNewParty->cPartyName);
return 0;
}
Output Screen
-
7/31/2019 Trainee Material
26/40
Solution - I
#include
typedef struct Party
{
int iPartyId;
char *cPartyName;
}Party;
int main()
{
Party *pNewParty=NULL;
pNewParty = (Party*)malloc(sizeof(Party));
pNewParty->cPartyName = (char*)malloc(50,sizeof(char));
pNewParty->iPartyId = 10;
strcpy(pNewParty->cPartyName,"Alocious");
printf("Pointer Addr:\t%p\n",pNewParty);printf("PartyId:\t[%d]\nPartyName:\t[%s]\n",
pNewParty->iPartyId,pNewParty->cPartyName);
return 0;
}
Output Screen
-
7/31/2019 Trainee Material
27/40
Solution II
#include
typedef struct Party
{
int iPartyId;char *cPartyName;
}Party;
int main()
{
Party *pNewParty=NULL;
pNewParty = (Party*)malloc(sizeof(Party));
pNewParty->cPartyName = (char*)malloc(50,sizeof(char));
pNewParty->iPartyId = 10;
pNewParty->cPartyName = strdup("Alocious");
printf("Pointer Addr:\t%p\n",pNewParty);
printf("PartyId:\t[%d]\nPartyName:\t[%s]\n",pNewParty->iPartyId,pNewParty->cPartyName);
return 0;
}
Output Screen
-
7/31/2019 Trainee Material
28/40
Solution - III
#include
typedef struct Party
{
int iPartyId;char *cPartyName;
}Party;
int main()
{
Party oOldParty;
Party *pNewParty = &oOldParty;
oOldParty.cPartyName = (char*)malloc(50,sizeof(char));
oOldParty.iPartyId = 10;
strcpy(oOldParty.cPartyName,"Alocious");
printf("Pointer Addr:\t%p\n",pNewParty);printf("PartyId:\t[%d]\nPartyName:\t[%s]\n",
pNewParty->iPartyId,pNewParty->cPartyName);
return 0;
}
Output Screen
-
7/31/2019 Trainee Material
29/40
How to make a Domain Application*:
From the Domain Analyst , the Domain requirement may be came by either
as document or pdf or oral.The Programmer have to convert that requirement in to
Structures and Signatures . The structures are nothing but the group of related data for
the given domain requirement in an organized mannar.After that Using those structures
create the signatures ,The signatures are nothing but the flow of functions invoked while
tigger an event.*--> The Examples contains less content for understanding purpose.The Actual content 'll moreWhat do you meant by Event:
The Event is an action what an Applictaion 'll perform.For example, Lets
take a Domain called OMS(Office Management System).In the OMS, There are many
modules are there namely Enquiry, Quotation, Order, GRN, DC, Invoice,GoodsReturn, Party, Accounts, etc.., In that modules, It can contains the action like
search, Create, Update ,Delete, Restore, etc.., are termed as events.
If we write a function for an event means the function should be prefixed
with Run. Note that the prefix should not be suited for any other subfunction.
Each Events may or may not have set business rules or business
validation.That business rules were narrated via document or oral by Domain Analyst
For Example, we took the Enquiry, where imagine the Enquiry is you are the shopkeeper
professionally you'll enquire rate and details of some item or product from many different
shops. The enquiry which is made by you is purchase enquiry. To whom it has been
made is Supplier.When someone Enquire from you is the Sale Enquiry, the person who
enquired is termed as Customer. The customer and supplier has same set of
parameters. So, we call them as Party.
Eg for Signature(Function) naming for Events.
RunCreateEnquiry(......)
RunUpdateEnquiry(......)
-
7/31/2019 Trainee Material
30/40
How to construct a Structure for Domain Requirement:
The construction(Design) of structures should be simplified and use to put
the variables whereever required for optimized search and minimal consumption of
memory.
Lets see some examples,First we'll take the Party screen and designstructure for it.
Screenshot:
One of the Event
Parameters
-
7/31/2019 Trainee Material
31/40
Typedef struct PartyEntity{int iPartyID;
int iName;
/* cPartyType - 2-bit--[0-customer/1-supplier/2-Both]
- 2-bit--[Company Classification]
[ 0-Manufacture/1-Industry
/2-SEZ /3-Others]
*/
char cPartyType;
Container *pPartyAddress;
int iContactPerson;
int iContactNo;
int iMobileNo;
int iFAXNo;
int iEMailId;
Node *pTaxOrientedNo;
int iAsOnDate;
float fOpeningBalance;
float fDueAmount;
NODE *pSalesInstrument;
NODE *pPurchaseInstrument;
}PartyEntity;
Char cPartyType-- Here this
parameter holds 2 parameter
value as described above in Blue
color Font.If write a normal mean
it'll like below
char cType;
char cCompanyClassification
Because of this one byte'll be
wasted. So while designing
structures you have to combined
the parameter like this.To avoid
wastage. This is applicable only
parameters having defined value
This variable is designed as a pointer
Because that variable holds Tax
oriented nos like (PAN No,TIN No,
CST No,etc).But all party donot have
this so here minimal wastage of
memory.Due to the memory 'll be
created when those no exist.
The variable is not given by DomainAnalyst.But the Developer has to
thing and introduce some variables
like this.For fast Retrival due for the
party. Introduce variables whereever
it required.Keep it mind This is for
fast access.
These 2 variables means where the party
do any transaction'll be pushed here.so
that we can retrive all the transaction
made by the party.. We can as simply say
it as an Object in OOPs concept.If we
take a party we can get records with
respect to him.
Typedef struct SaleInstrument
{
Container *pEnquiry[3];
Container *pQuotation[3];
Container *pOrder[3];
Container *pDC[3];
Container *pInvoice[3];
Container *pGoodsReturn[3];
Container *pPaymentOrReceipt[2];
}SalesInstrument;
-
7/31/2019 Trainee Material
32/40
Lets take another Example Enquiry :
screenshot:
The Item should be list because One Enquiry
may contain many items
Decides Purchase or Sales flow
-
7/31/2019 Trainee Material
33/40
Typedef struct ItemDetails
{
Node *pItemRef; // StockItemRef or PreviousItemRef
char cStatus; // 0 - StockRef, 1 - PrevItemRef
int iDescription;
float fQuantity;
int iUOM;
}ItemDetails;
typedef struct EnqQuoOrdItem
{
ItemDetails pItemDetails;
float fRateUOM;}EnqQuoOrdItem;
typedef struct Enquiry
{
int iNo;
int iDate;
int iRemarks;
char cStatus;
Container *pEnqQuoOrdItem;
Node *pParty;Container *pNextInstrument;
}Enquiry;
-
7/31/2019 Trainee Material
34/40
Lets see for quotation: Load the Previous Enquiry. If the user made
the quotation with respect to Enquiry
-
7/31/2019 Trainee Material
35/40
Typedef struct Quotation
{
int iNo;int iDate;
int iRemarks;
char cStatus;
Container *pEnqQuoOrdItem;
union{
Node *pParty;
Container *pPrevInstrument;
};
Container *pNextInstrument;Node *pTermsConditions;
float fTotAmtPerUOM;
}Quotation;
Here We use union, Because the quotation
can be made via Enquiry or Directly. If
quotation is come via Enquiry means that
Enquiry Node in the variable
pPrevInstrument and If Direct means
holds party in the variable pParty.
The cStatus 'll give information about what
is stored
typedef struct OMS
{
CONTAINER *pCompanyProfile;
CONTAINER *pParty[3];
CONTAINER *pEnquiry[2][3];
CONTAINER *pQuotation[2][3];
}OMS;
pParty ,Here the party is in array because
as we already discussed the party 'll
Customer,Supplier,Both..,With respect to
the party Type the party node'll be inserte
in respective index.
Each part Domain has its main structure,as simply
says that is the database for that domain, it contains
all the root pointer or head pointer if required
when an event is triggered the checking also go
from here and the final node should be inserted in
corresponding root if required
Enquiry
node 'll be
inserted Here
Quotation
node 'll be
inserted Here
This array for sales
and Purchase
This array for current
status of that Instrument
Pending/moved/closed
-
7/31/2019 Trainee Material
36/40
How to construct signatures:
The signatures are nothing but the function prototypes, which is used to
satisfy the domain requirement or business needs.When an event(create,update..)
triggered an set of functions should be called those functions are arranged in a flow with
its prototype using that flow itself we can check whether the event 'll completely work ornot.Actually the construction of signatures is equivalent to code.Let see how to construct.
'll we take the Party for the event Create(Save).
On save of party we've to check the following things.Note that the business
rules which mentioned below is minimal for understanding purpose.But the actual
content 'll be more.
1. Check whether the party is already exist
2. Generate the unique Id for the party.
3. Check whether the AsOnDate is not future date.
4. Check whether the AsOnDate is not lesser that Company start date.
int RunCreateParty(OMS *OMSRoot,PartyEntity *pInputParty);
int IsValidAsOnDate(int iCompanyProfileDate,int iAsOnDate);
int IsNotFutureDate(int iAsOnDate);
int GetCurrentDate(int *iCurrentDate);
int IsGreaterThanOrEqual(int iAsOnDate,int iCompanyProfileDate);int GetBitStream(int cPartyType,int iBitPattern,int *pPartyType);
int IsPartyAlreadyExist(CONTAINER *pPartyRoot,int iPartyName);
------If all the above condition TRUE.
int SetUniqueId(int *iPartyId,int iModuleNo);
int CreateAndCopyPartyNode(PartyEntity **pPartyNode,PartyEntity *pInputParty);
int AssignContainer(CONTAINER **pPartyRoot,NODE *pPartyNode);
These are the business rules tobe considered
while creating a party.If it fails the operations
should be aborted.
After the business rules satisfies an Unique Id should be created and
and allocate the memory for the party because while we get from user
we can't assure that the node is created by using malloc or calloc.so
create a node and copy the contents from input node to new node.
After that we have to persist the data so Insert the new node in the party root
in the OMSRoot w.r.t. its type.
Is- When the function
characteristic'll be 0 or 1
i.e.., True or False
-
7/31/2019 Trainee Material
37/40
Codes for above Signatures:
Note: Error means return Non-Zero,Success means return Zero
Every function should follows.
Normal RunCreateParty Code:
Int RunCreateParty(OMS *pOMSRoot,PartyEntity *pInputParty)
{
PartyEntity *pPartyNode=NULL;
int iPartyType = 0 ;
if(!pInputParty || !pOMSRoot)
return -1;
if(!pOMSRoot->pCompanyConfig)
return 1;
if( IsValidAsOnDate(pOMSRoot->pCompanyConfig->iCompanyStartDate,
pInputParty->iAsOnDate) )
return 1;
GetBitStream(pInputParty->cPartyType,0x3,&iPartyType);
if( !IsPartyAlreadyExist(pOMSRoot->pParty[iPartyType],pInputParty->iPartyName))
return 1;
SetUniqueId(&pInputParty->iPartyId,1);
CreateAndCopyPartyNode(&pPartyNode,pInputParty);
AssignContainer(&pOMSRoot->pParty[iPartyType]),pPartyNode);
return 0;
}
Our Expectational Style:
Int RunCreateParty(OMS *pOMSRoot,PartyEntity *pInputParty)
{
PartyEntity *pPartyNode=NULL;
int iPartyType = 0 ;
if(!pInputParty || !pOMSRoot)
return -1;
if(!pOMSRoot->pCompanyConfig)
return 1;
return ( IsValidAsOnDate(pOMSRoot->pCompanyConfig->iCompanyStartDate,pInputParty->iAsOnDate)|| (GetBitStream(pInputParty->cPartyType,0x3,&iPartyType))
|| (!IsPartyAlreadyExist(pOMSRoot->pParty[iPartyType],pInputParty->iPartyName))
|| (SetUniqueId(&pInputParty->iPartyId,1))
|| (CreateAndCopyPartyNode(&pPartyNode,pInputParty))
|| (AssignContainer(&pOMSRoot->pParty[iPartyType]),pPartyNode));
}
-
7/31/2019 Trainee Material
38/40
Normal IsValidAsOnDate Code:
Int IsValidAsOnDate(int iDate,int iAsOnDate){
if( !IsFutureDate(iAsOnDate) )
return 1;
if( IsLesser(iAsOnDate,iDate) // If Error Returns in Lesser means GreaterThanOrEqual.
return 0;
return 1;
}
int IsFutureDate(int iAsOnDate)
{
int iCurrentDate = 0;GetCurrentDate(&iCurrentDate);
if( IsGreater(iAsOnDate,iCurrentDate) ) // If Error in Greater Means LesserThanOrEqual
return 1;
return 0;
}
int IsLesser(int iLesser,int iNonLesser)
{
if( iLesser < iNonLesser)
return 0;return 1;
}
int IsGreater(int iGreater,int iNonGreater)
{
if( iGreater > iNonGreater)
return 0;
return 1;
}
-
7/31/2019 Trainee Material
39/40
Our Expectational IsValidAsOnDate Code:
Int IsValidAsOnDate(int iDate,int iAsOnDate){
return ( !IsFutureDate(iAsOnDate) ) || ( !IsLesser(iAsOnDate,iDate) );
}
int IsFutureDate(int iAsOnDate)
{
int iCurrentDate = 0;
GetCurrentDate(&iCurrentDate);
return ( IsGreater(iAsOnDate,iCurrentDate) );
}
int IsLesser(int iLesser,int iNonLesser)
{
return !( iLesser < iNonLesser);
}
int IsGreater(int iGreater,int iNonGreater)
{
return !( iGreater > iNonGreater);
}
-
7/31/2019 Trainee Material
40/40
For Practice:
1. Make the IsPartyAlreadyExist into COMMON function with reference to the
previous sections.
2. Use to make GetBitStream and SetBitStream with your own Parameters.
Int IsPartyAlreadyExist(CONTAINER *pPartyRoot,int iPartyName)
{
while( pPartyRoot && ( ((PartyEntity*)pPartyRoot->pDataPtr)->iPartyName != iPartyName))
pPartyRoot = pPartyRoot->pNext;
return !(pPartyRoot);
}
int CreateAndCopyPartyNode(PartyEntity **pPartyNode,PartyEntity *pInput)
{
*pPartyNode = (PartyEntity*)calloc(1,sizeof(PartyEntity));
memcpy(*pPartyNode,pInput,sizeof(PartyEntity));
return 0;
}