2.1 Compiling in Microsoft Visual C++ 1.5 in Windows 3.1
We can use even old C programs in this new environment.
We utilize Windows Programming only for large software
implementation .
The procedure for compiling will be,
1. Open the MSVC by clicking its icon.
2. Using file open click the filename.c.
3. In projects click compile or build.
4. If the compilation and linking is successful, you can now click the execute.
2.2 Necessary Topics in C/C++
2.2.0 Pointer
int p integer
int *p pointer to integer
int *p[3] array of 3 pointers to integer
int (*p)[3] pointer to an array of 3 integers (?)
int *p() function returning a pointer to an integer
int (*p)() pointer to function returning an integer
2.2.1 String Manipulation
char s[255];
int i;
for (i=0;s[i]!='\0';i++); \0=null character=ASCII 0
\\...after the loop, i=length of string
Although C appends '\0' automatically, it is the responsibility of the
programmer.
|
char alphabet[27],letter;
int index;
for (index=0,letter='A';letter<='Z';index++,letter++)
alphabet[index]=letter;
alphabet[index]='\0';
printf("%s\n",alphabet); automatic ends to '\0'
|
|
2.2.2 Strings as Parameters
|
char strvar[20];
count=string_length(strvar);
\\...
void string_length(char str[]) ---str[] has no array bound
{
\\...
}
or you may use
void string_length(char* str)
|
|
2.2.3 Minimizing Source Code
for (i=0;s1[i]!='\0';i++)
s2[i]=s1[i];
s2[i]='\0'; <---affix null
This can be shortened to
for (i=0;(s2[i]=s1[i])!='\0';++i); <--semi-colon required
When s2[i]='\0' the loop terminates and null has been assigned to s2[]
already. In C, the boolean FALSE=0. The code can be shortened further to
for (i=0; (s2[i]=s1[i]); ++i);
The loop terminates if the statement (s2[i]=s1[i])=0
Notes:
1. Is speed more important than reliability?
2. Is the code as simple as possible?
3. Does the code maintain readability?
2.2.4 Case Manipulation
|
"a" ASCII code 97 = 0 1 1 0 0 0 0 1
"A" ASCII code 65 = 0 1 0 0 0 0 0 1
128 64 32 16 8 4 2 1
To Lower Case
"A"|32="a" |-bitwise or The 3 bit operators
0100 0001 "A" &-bitwise and
or 0010 0000 32 ~-compliment
------------
0110 0001 "a"
To Upper Case 32= 0010 0000 The value 32
"a"&~32="A" ~32= 1101 1111 after the compliment
a= 0110 0001
~32= 1101 1111 &
---------------
A= 0100 0001 The result after performing &(~32) on "a".
Compliment of 32 is performed first, then bitwise AND.
void str_to_uppercase(char s[])
{int i;
for (i=0;s[i];i++) --loop terminates when s[i]='\0'
if (s[i]>='a'&&s[i]<= 'z') s[i]=s[i]&~32;
} s[i]&=~32 <--compact
void str_to_lowercase (char s[])
{int i;
for (i=0;s[i];i++)
if (s[i]>='A'&&s[i]<='Z') s[i]=s[i]|32;
} s[i]|=32; <--compact
|
|
2.2.5 White Space
blank ASCII 32 'b'
tab ASCII 9 '\t'
2.2.6 String Comparison
|
for (i=0;s1[i]==s2[i];++i)
if(s1[i])=='\0')
{printf("Equal strings\n");
...}
exits the loop when 1. s1[i]!=s2[i]
2. s1[i]='\0'
With Ignore Case, AAA=aaa
int equal_strings(char s1[], char s2[])
{int i;
char a,b;
for (i=0; s1[i]&&s2[i];i++) <-operator AND,loop stops if
if (s1[i]!=s2[i]) s1[i]='\0' and/or s2[i]='\0'
{a=(s1[i]>='a'&&s1[i]<= 'z')? s1[i] &= ~32: s1[i];
TRUE if lowercase to_upper_case
b=(s2[i]>='a'&&s2[i]<='z')? s2[i] &= ~32: s2[i];
if (a!=b) return 0; <--unequal string
}
After the for-loop s1[i]='\0' and/or s2[i]='\0'
if(s1[i]||s2[i]) return 0; <--unequal string
else return 1; <--equal string
|| - must be operator XOR
Must be equal in string length
|
|
2.2.7 Pointer Manipulation
int a=5; &a = address of a
pointer - is a variable that contains memory address
int *int_pointer,b
int_pointer=&b
b=*int_pointer use (*) to get the value
---------------------------
int i,*iptr;
iptr=&i
*iptr=5; <-- results to i=5
2.2.8 Call by Value
main ()
{ int a=5, b=10;
some_function(a,b);
printf("main a=%d b=%d\n",a,b);
}
some_function(int a,int b)
{printf("somef a=%d b=%d\n",a,b);
a=9;b=11;
printf("somef a=%d b=%d\n",a,b);
}
result: somef a=5 b=10
somef a=9 b=11
main a=5 b=10 <--unchanged
2.2.9 Call by Address
main ()
{int a,b;
initialize(&a,&b)
}
initialize(int *a, int *b)
{*a=1;
*b=2;
}
Passing an array address, Reading input file
The line data can be;
0 1 0.01 0.01
2 3 0.084 0.037
99 0 0 0
where it is called free-format. Separation between data is a comma
or several white spaces. The code looks like;
|
#include
int kp[10],kq[10] etc nl=0;
float x1[10],x0[10];
void main (void)
{file=fopen("filename.ext", "r");
while (1) <--infinite loop
{nl++;
fscanf(file,"%d %d %f %f",&kp[nl],&kq[nl],&x1[nl],&x0[nl]);
if (kp[nl]==99) break; <--exit the while block
etc...
} <--while block
}
kp <--means address of kp[0]
Since array and pointers are synonymous
kp+nl, kq+nl,x1+nl,x0+nl is equivalent to --> &kp[nl] etc..
|
|
The compiler takes care that nl*2 bytes for integers and nl*4
for float in kp+nl, x1+nl (which address to use).
&(kp+nl) = is error in C because kp is already an address.
2.2.10 Pointer Schemes
(*a)++ =post-increment its value
while (*a++) =the value is used in the while loop,
then increment the address.
++(*a) or ++*a =get the value then increment that value
*++a =increment address, then get its value
2.2.11 Pointers and Strings
char s[20];
show_string(s); <--passes &s[0]
\\...
void show_string(char *r)
{while (*r) printf("%c",*r++)
-------
void string_length(char *s)
{int len=0;
while (*s++) len++; for (len=0;*s;len++,s++);
return (len);
}
2.2.12 Ascii To int
"value" is the integer result from the string str. At line_4, the char pointer
str moves to a non-blank character. That first character can be a + or -
sign. Line_6 moves the pointer after that +/- and sign gets -1 or +1. Line_7
loops until the terminating value=0 is reached and checks if that character is
ascii 0 to 9. If it is a different character, returns (-1), otherwise, the value
is moved to "tens" position and adds the integer equivalent by subtracting
the ascii position of zero=48. At line_11, its value is multiplied by the sign
and normally returns (0). So the returned value of (-1) means an error code.
|
1. void ascii_to_int(char *str,int *value)
2. {int sign=1; //-1 if negative
3. *value=0;
4. while(*str==32) str++; //blank=32, skip leading blanks
5. if (*str=='-' || *str=='+')
6. sign=(*str++=='-')? -1: 1;
7. while (*str) <-end of string is *str='\0'
8. if ( (*str>='0')&& (*str<='9'))
9. *value=(*value*10) + (*str++ - 48); //'0'= ASCII 48
10. else return (-1); //invalid character
11. *value *=sign;
12. return (0);
13. }
|
|
2.2.13 Passing Address and Reference to Function Calls
Passing by reference is neater because your code seems ordinary. Both
situation gets the passed variables modified upon return. Without this "*"
in line_1 and "&" in line_9 the said function is passed by "value". Passed
by "value" will not alter the variables upon return.
|
Passing by Address
1. void swap(int *a, int *b)
2. {int temp;
3. temp=*a; *a=*b; *b=temp;
4. }
5. void main()
6. {int x=2,y=3;
7. swap(&x,&y); //<--passing address
8. }
Passing by Reference
9. void swap(int &a,int &b) //<--passing an alias
10. {int temp;
11. temp=a; a=b; b=temp; //no need for pointer *
12. }
13. void main()
14. {int x=2,y=3;
15. swap(a,b);
16. }
|
|
2.2.14 Array of Pointers
<<2.3.0 Declaring Structure in C
A C++ class declaration is an outgrowth of the C structure declaration. In C:
struct Point <--Point is a structure.
{int x,y;}
...
struct Point ul,ur; <--declaring a data type. ul,ur are instance of Point.
ul.x +=ur.x; <--accessing the member of the structure
--------
typedef struct
{int x,y;} Point;
...
Point ul,ur={0,0}; <--no need for structto declare a data type. ul,ur correspond to C++ objects
Point *m;
ul.x+=m->x; <-- accessing a member of a pointer;
2.3.1 Declaring a Class
Files must have an extension name "cpp". A file with *.c that contains
classes will not compile.
Class visibility uses private, public, protected keywords to variables sometimes
called "members" and functions sometimes called "methods".
2.3.2 Scope Resolution Operator ::
The scope resolution operator has the highest precedence.
|
int N,count=0;
void main(void)
{
//
}
void how_many(float w[], float x, int& count)
{for (int i=0; i< N; i++)
count+=(w[i]==x);
++::count; //keeps track of calls
}
|
|
2.3.3 static Member
Data members can be declared with storage class modifier static.
The variable declared static is stored uniquely in one place and is shared by
all objects declared to that class. Methods can be declared with static modifier
also.
2.3.4 A Friend Function
The keyword friend is a function specifier. It gives a non member function
access to the private members of a class. One reason for using friend functions
is that some functions need access to more than one class. If all member functions
of one class are friend functions of a second class, this can be specified by
writing friend class classname.
|
class one
{friend void function1(); //friend function
int function2(); //member function
int function3();
float function4();
. . .
};
class two
{. . .
friend int one::function2(); //function of class one with
. . . //access to variables of class two
}
class three
{. . .
friend class one; //all member functions of class one
. . . //have access
}
void function1() //has access to variables of class one
{
. . .
}
|
|
2.3.4 A Friend of 2 Classes
Consider multiplying a matrix by a vector. A matrix is a class and a vector
is another class. The resulting product is a vector returned by the friend function.
|
class matrix; //forward reference
class vector
{private:
float p[10];
int size;
friend vector multiply(const vector& v, const matrix& m);
public:
. . .
};
class matrix
{float b[10][10];
int row, column;
friend vector multiply(const vector& v, const matrix& m);
public:
. . .
}
vector multiply(const vector& v, const matrix& m)
{int i,j;
vector answer;
if (v.size != m.column) exit(1); //not compatible for multiplication
for (i=0; i< m.row; i++)
{answer.p[i]=0.0; //initialize the totalizer
for (j=0; j< m.column; j++)
answer.p[i]+=m.b[i][j]*v.p[j];
}
return (answer);
}
|
|
2.4 Complex Arithmetic in C++ using Friend Functions
Output of the program shown below.
Some Code Explanation
Although there is no word "private", variables real and imag are private.
Lines _6 and _7 are two constructors. The first one refers to when you
declare like "complex z;" without an initialization. The second constructor
has an initialization like "complex a(2.5,3.0);"
In line_12 and _13 use or no use of "const" and "&" does not make any
difference. "const" is just a safeguard that the variable will not get
altered inside the function. The "&" simply means that you are passing
a reference. Any modification of the variable will be reflected back. It
is a neat way compared to passing a pointer. "friend" is an access modifier
to functions that are not members of the class. So the functions add() and
myprint() are not members of class complex. They can access a.real because
they are permitted with the "friend" prefix. In the main program, you
may include "float x;" then later "x=a.real;". This will cause an error
because a.real is a private data. It can be permitted if you defined real
to be "public". To access "private" variables, you need the member getReal(),
as "x=a.getReal();".
Without the use of overloaded operator in line_13, you may add complex numbers
using a call like in line_56 "d=add(a,b);" instead of a neater call like "d=a+b;".
You are allowed a call in line_63 "d=operator+(a,b);"
The overloaded operator is a "friend" and not a member function because
the said function does not operate on the (*this) object. This particular
friend function "friend complex operator +(.." can be made a member
function but the concept is trickier. The declaration as a member inside the
class is:
1. complex operator +(const complex& b);
The definition will be;
2. complex complex::operator +(const complex& b)
3. {
4. real+=b.real;
5. imag+=b.imag;
6. return *this;
7.}
and you may use "d=a+b;" or
8. d=a.operator+(b);
This is trickier because the variable a is not included in line_1. Never specify the first argument when writing overloaded operator member functions
because the first argument of all member functions is the *this pointer. The *this
pointer is always passed to member functions no matter what else you pass to the
member functions.
Friend functions are given access to the private variables using the dot
operator. It can not access without the use of the dot operator.
It can not access the (*this) too.
Can the member function "complex operator +=(complex& c);" be made a friend
function? The answer is no, because this function access the left side of
"d+=a;", the "d" as the "this". A friend function can not access the "this".
You may however use friend complex operator +=(complex a, complex b) and return
another complex, but who will receive the returned value? In "d+=a;", the "d" becomes
the first argument and "a" becomes the second. No one will received the returned
argument.
Can we make the friend function "friend complex add(complex a, complex b);"
as a member instead? Yes, but the code will be different.
|
complex complex::add(complex a, complex b)
{//complex c;
real=a.real + b.real;
imag=a.imag + b.imag;
return *this; <--use of this will modify d.real ,d.imag in the
} d.add(a,b) call
and the call will be
d.add(a,b); instead of
d=add(a,b);
|
|
2.5 Using Overloaded Operators, completing the Class Complex
Output of the program shown below.
As before, the default constructor has a declaration as "Complex z;" and
line_15 sets its variables to zero. Lines_19 to _22 are methods or
member functions. Why not friend functions? All of these operates on the
self reference objects defined by the lvalue as the first parameter
and returns (*this) which is equated back to the lvalue. Lines_25 to _30
are friend functions where 2 parameters are passed. These functions do not
use the (*this) member variable.
Note the meaning of unary operator in location_101, -a;
where we could not do this in other programming languages. So in the statement d=-a; will cause a problem if you do not intend to negate a
within a itself. The proper way to do this is d=a; -d; And a is unchanged.
2.6 Utility Program Lister.c
This is a small program used to append line numbers on the beginning of the source code. Although this is
not part of algorithms development, it will aid in explaining the source code. Shown below is the code with
numbering on the left side. This is the result of executing the file itself.
Some Code Explanation:
1. We do not have an error checking in Line_25.
2. In Line_27 our destination output is a fixed filename: "output.txt"
3. The main program will loop on Line_28. Inside the parenthesis is declared a BOOLEAN function. It will
return only TRUE=1 or FALSE=0. Loop will stop only when the function returns FALSE.
4. Line_38 and Line_39 are the output of the program. One on the CRT and another on a file to be used later on
a word processor.
HOME
CHAPTER ONE: INTRODUCTION
CHAPTER TWO: PROGRAMMING TOPICS
CHAPTER THREE: MATRIX INVERSION ROUTINE
CHAPTER FOUR: STEP-BY-STEP ALGORITHMS
CHAPTER FIVE: DIRECT METHODS IN Ybus FORMATION
CHAPTER SIX: SPARSITY
CHAPTER SEVEN: MATRIX FACTORIZATION AND OPTIMAL ORDERING
CHAPTER EIGHT: SPARSE Zbus FROM FACTORED SPARSE Ybus
CHAPTER NINE: FAULT CALCULATIONS
REFERENCES