Sender: MARS (Fangq), News District: Programming
Title: [HTML] Delphi for C Programmers
Sending station: The Big Green (sat jul 27 01:36:29 2002), transfer
Delphifor C Programmers
Introduction
There Are A Lot of Delphi Books Out There, But 99% of Them Deal Only with the THE
More "Glamorous" Visual Aspects. While The Visual Interface Is The Main
Attraction of Development Systems Like Delphi and Visual Basic, Their Greatest
Stregth Is That They Free The Program from The Drudgery of Coding The User
Interface, And Allow Him or Her to Work On The Actual Program.
IT Doesn't Matter How Visual Your Tools Are (or How Fantastic T
Manufacturer's Claims, You Won't Accomplish Much without Actually Coding T
Logic behind the interface.
THIS TEXT IS Meant TO AID C Programmers in The Transition to Object Pascal.
Although The Main Features of Both Languages Are Relatively Similar, There Are
Certain Small Differences That Can Be Confusing, Especially When the Lead The
Programmer INTO MAKING IncorRect Assumptions.
THE MAJOR
Differences
There Are Three Main C Features Missing from Object Pascal, THESE Are:
Multiple Inheritance, Templates and Overloading. i
CAN Hear The Groans Now, But Don't despair. Object Pascal Has Enough Great
Features to more Than Compensate for these OMIMIMIMIMY OBJECT
Pascal Features That Are Missing from C (and They Have Nothing to do with THE
"Visual Thing").
Other Major Differences Include:
COMMON BASE CLASS - IN Delphi, All Objects Descend from Tobject.
2.
3. No Stack Objects - IN C You can create Objects on the stack or on the
4. HEAP. All delphi Objects are created on the heap, and reference via pointers.5.
6. Full RTTI - Delphi's Run Time TYPE INFORMATION IS MORE COMPLETE THAN C 's.
7.
8. Class References - In C you always work on Objects, But in Delphi, You CAN
9. Also Work On Uninstantiated Classes.
10.
11. Properties - a Very User-Friendly Language Extension. It's like designating
12. Methods to Be Executed Upon Reading from, or Writing To, A Data MEMBER. (THIS
13. Can Be Implement In C , But it's not as simple. Check Out The C section for more details.)
14.
Pointers
Pointers Give C a Lot of It's Power and Flexibility, But They Are Also The
Cause of MOST MAJOR BUGS. There Are Pointers in Pascal Too, But The Compiler IS
A Little More Protective (Or Restrictive, Depending On Your Point Of View).
DECLARING &
DE-referencing
The syntax for declaring Pointers in Pascal is Similar To The One Used IN C.
The main Difference Being That The Caret ("^") Is Used INSTEAD of The
askISK ("*
"): {Declare
a Pointer to a character
} Charptr: ^ char; to de-reference
A Pointer, The Caret Is Placed on The Right Hand Side of The Right Hand Side of THE
Variable: {set
Mychar to what charptr Points To
} Mychar: =
Charptr ^; WhatVER FOLLOWS THE CARET MUST Be a Defined
TYPE. You can't Directly Create a Pointer to an Array,
Structure or class. You Must First Define these As Types
Before you can create pointers to them.
While In C you can do this:
// Pointer to a Pointer to // an
Array of 5 Characters Char
** Charrrptr [5];
>
In Pascal You are Required to do it in steps:
Type
{Define Type: Array of 5 Characters
} Tcharr = array [0..4] of char; {Define Type: Pointer to Tcharr} Tpcharr = ^ TCHARR; VAR {DECLARE
Variable as Pointer to Type Tpcharr}
Charrrptr:
^ TPCHARR;
Indexing
THIS May Come Asia Shock to Most C Programmers, But in Pascal, As a general
Rule, Pointers CAN't Be Indexed. a Pascal Pointer Lets you Reference One, and And
Only One Object In Memory. This Rule Is Not As Limiting AS It May Seem At First,
Since the Object That You Reference Through The Pointer Can Be An Array, A
Structure or a class.
When you need a pointer to a list of integers, you use a pointer to an arch
Of Integers INTEGER. You Still CAN't Index A Pointer
To an array, but you can it. The array itself. The way to attbo ketmomplish this is
By de-referencing the pointer before using the index.
For these declarations:
Type <
/ tt> {
Declare Type: array of 101 char
} Tchararr = array
> <> color = "# 808080"> [0..100] OF
CHAR;
{declare Type: Pointer
To an array of 101 char
} TCharrptr
=
^ Tchararr; Var
{declare a pointer to an array of 101 char
} Myptr:
TCharrptr;>>>>>
The Following Facts Apply:
{THIS
Is Wrong, Can't Index a Pointer} x
: = MyPTR [10];
{THIS IS FINE.
DE-referencing the pointer} {gives you an array, Which can be indexed
} X: =
Myptr ^ [10];
Allocating &
Deallocating
Just Like In C, The Delphi Programmer Is Responsible for the allocation and
Deallocation of Pointer Space. There Are SEVERAL WAYS OF Allocating Memory for
Pointers. The Simplest One is Through The Procedure "New".
The Procedure "New" Allocates The Exact Amount of Memory Needing for thispecified Pointer. Using The Previous Example:
NEW (<
/ TT> MYPTR);
Alltructs Exactly 101 Bytes to "Myptr" (Since It Points to an Array of 101
Characters).
There is also another form of "new", a function, Which year be used for the
Same Purpose. in this version, The parameter is a type, not a variable. The
Return Value is a Pointer to the allocated space.
Myptr: =
NEW (> Tchararrptr <> color = "# 808080">);
This Is A Tad More Complicated, But Would Be Useful if You Wanded to Allocate
Memory for One Type of Data, But Wanted to Point To It with a Different Type
Pointer (Like an Undyped Pointer).
To deallocate the memory allocated with "new", you must use
"Dispose":
Dispose (MyPTR> <> color = "# 808080">);
If you want to beable to specify the exact amount of memory to allocate, you
Can use the "getmem" procedure. To allocate the 101 bytes
Needed for "Myptr", you would do the folowing:
GetMem (MyPtr> <> color = "# 808080">,
101);
Allocating More Than The Space Required Is A Waste of Memory, Since Delphi
Won't let you index it anyway (see the section "Range Checking and Pointers).
Allocating Less Could Cause Serious Problems if you write to the unallocate
Part of the variable.
To deallocate this memory, you must use "freemem", and you
Must Explicitly State The size of the allocated memory:
FreeMem (MyPTR, 101);
Range checking and
Pointers
When You Declare An Array, You Must Specify An Upper And Lower Value for IT'S
Index. The Pascal Compiler, Unlike C's, Performs Range Checking To Ensure Thatyou Don't Use An Out of Bounds Index. This Offers Additional Protection Against
Memory Overwrites, But Has An Unexpected Side-Effect (Unexpected for C
Programmers That I): Pointers to Arrays Are Also Range Checked.
Since you are responsible for allocating memory for the array pointer, and
You can allocate as much or ask, you may be tempted to
Assume That You can use as high an index as you need. this is not the case.
Remember That You can't really index the pointer. You must de-reference the
Pointer and kilies, Since The Array Has Specific Index Boundaries,
You are construined by them.
Dynamic
Arrays
>
So, What happens if you need? Well, Pascal WAS
Never Meant to Support Variable Size Arrays. However, There is an easy, IF
Rather INELEGANT, WORKAROUND (E.G. a Hack). What You Must Do IS Declare A
Pointer to an Array As Big As It Can Possibly Be. in 16 Bit Delphi, this size
Limit happens to be 32,767 bytes (32k), But in Delphi 2.0, you have a little
More Space; About 2,147,483,647 bytes (Yes, That's 2GB!). The Upper Bound of The
Array Would Be this Number Divided by The length of the array's type:
CONST MAX_SIZE = 2147483647;
Type <
/ tt> TMYARR = Array
> <> color = "# 808080"> [0 .. (max_size
Div
SIZEOF (Atype)]]
Color = "# 800000"> of Atype; tmyptr = ^ TMYARR; After this, you can Declare Variables of Type Tmyptr, And Allocate as a the on the door. The only thing to keep in Mind, IS That for All Practical Purposes, You Won't have ing. By The Way, Don't Be deceived Into Thinking That You can use any match Mathematical Expression in The Declaration of an Array. Only Constant Expressions, Those That Can Be Resolved At Compile Time, Can Be Used Here. I Must Point Out That You Will Rarely Need To Perform Any of these Steps. Delphi Comes with a Very Useful Class Called TLIST WHICH Implements all of the functionality of a dynamic array of pointers. Since All Objects are Pointers, you can use tlist with them. if you need An Array of strings, you can use tstringlist. I Only BothereED with the Above Explanation, Because I Think IT Will Give C Programmers An Insight Into How Things Work In Pascal. Strings In Pascal, You Do Not Generally Need Character Pointers for Text. There's A String Data Type That Simplifies String Handling Immesely. Pascal Strings Are Particularly Easy To Use Because The Assignment and Addition Operators can be used to set and constnate them. Strings in 16 bit Delphi In Delphi 1.0, When You Declare A Variable of Type String, You can specify a size from 1 to 255 character the size, it DEFAULTS to 255. The first byte of the string (byte number zero) Contains the Length of the text this sell in the string. You do not incrude the length Bytehen declaring the size. MYVAR1: String [3]; {3 Chars Length Byte } Myvar2: string [255]; {255 Chars Length Byte MYVAR3: STRING; {255 Chars Length Byte } Myvar4: String [300]; {syntax error} Because of the length, pascal strings don't need Null-terminator. Although it is possible to directly read and set byte # 0, it is better not todting The "correct" Way of getting the length of a string is through the length Length Function. The Length Is Set Automaticly When You Assign or add a value to the variable. Changing The Length Byte Won't change the allocated size, only the size of The text. (Much Like Moving The Null Terminator In A C String). for Example, A 5 Character string 10: [0] [0] [0] [0] [0] [0] <-IF you Print this, IT WILL SAY: "" ". ^ -Length Byte If You Assigned It The Word "Hello", IT Would Look Like THIS: [5] [H] [E] [L] [L] [O] <-IF you Print this, IT Will Say: "Hello". ^ -> Length Byte If You Assign It The Word "Goodbye", IT Would Look Like this: [5] [g] [o] [o] [d] [b] <-IF you Print this, IT Will Say: "Goodb". ^ -> Length Byte As you can see, The Word gets truncated at the fiffh Character, Because The Variable IS Only 5 Bytes Long (Plus Byte # 0). IF You now Assign It The Word "Hi", IT Would Look Like THIS: [2] [h] [i] [o] [d] [b] <-IF you Print this, IT Will Say: "hi". ^ -> Length Byte Since "Hi" IS A Two Letter Word, The Length Byte Now Contains a "2". The Positions after the "I" Have Not Been Changed. Strings in 32 bit Delphi In Delphi 2.0, Strings Have Improved DramAtical. The maximum size for Strings is now 2 Gigabytes, and the isy denamically allocated. this means That You now Declare the without an initial size, and the strings grower and shrink as . The strings described in The Previous Section Are Still Available on Delphi 2.0, but the Type is now Called "shortstring". Also, if Youuse the old style declaration with a size between 1 and 255, you'll get a Shortstring: Var newstr1: String; {New Type of String } Oldstr1: String [255]; {Old Type of String } ildstr2: Shortstring; <> color = "# 408080"> {Old Type of String } newstr2: Ansistring; {New Type of String } There is also a new string related function: SETLENGTH. THIS Function Forces a string to reallocate itself To a specific size. this can be useful for truncating value, and for allocating Space for Character by Character Operations: Msg: = 'Hello'; {Allocs 5 bytes and sets to 'Hello' SETLENGTH (MSG, 3); {reallocs to 3 bytes (& truncates) } ShowMessage ( tt> msg); {Displays the Message 'Hel'}> SETLENGTH
Color = "# 808080"> (msg, 4); {reallocs to 4 bytes, adding a char } MSG [4]: = 'p';
Color = "# 408080"> {assigns 'p' to the last Char} showMessage ( tt> msg); {Displays the Message 'Help'} In General Individual Characters in A String Can Be Accessed by Indexing, Just Like Character Arrays In C, with the Exception That The First Character IS # 1 Instead Of # 0. Unlike C's Strings, Delphi's Aren't Pointers. If you assign one string to Another, The value is copied from the source to the destination. Here IS (Roughly) How A Delphi String Assignment Would Look IN C . 16 bits 32 BITS Char str1 [256]; char str2 [256]; ... strcpy (str2, str1); Char strong> * str1 = null; char * str2 = null; ... if (str2 strong>) delete str2; str2 = strong> new char [str1) 1]; strcpy (STR2 , str1); The Same Applies When Passing Strings As Parameters (Unless They're "Var" parameters). C style Strings There Are Times, Like When Making API Calls, When You Absolutely Must USE A C-Style Null-Terminated String. For this Reason, Delphi Lets you use c-style Strings Too. Their Type Is Known As Pchar, And as You May Have Already Guessed, They Are Character Pointers (But of a Special Kind). Unlike Strings, Pchars Must Be Explicitly Allocated and Deallocated. The functions use to allocate and deallocate pchars in Delphi Are Stralloc and strdispose. There is also a group Of functions use to manipulate the strings. a pleasant surprise is what of Names Are Almost The Same As Their C Counterparts. Some of these Are: Strcopy, Strcomp, Strcat and Strlen. There is also a function called strfmt That Works Just Like "Sprintf". Why has PChars A pchar is not exactly the sarm as a pointer to a char. As you already know, In Pascal, You Can't Index a Character Pointer. To Be Able To Access To Elements via indexing you would normally needed a pointer to an arrrey of CHARACTERS. Even, you would need to de-reference the pointer before Indexing it. The pchar is a new type what is treated in a special way by the Compiler So That It Works Exactly Like a char Pointer IN C. Objects IN C , There all, there is the stack ibject: on the stack or on the Heap. in Delphi, All Objects Are Created on The Heap. When You Declare A Variable as an Object Type, you are actually declaring a pointer. in thisexample: Var mylist:> TList <> color = "# 808080">; mybutton: Tbutton; > MYLIST IS ACTUALLY A Poin. Of Course, Unsteil You Assign Something To Mylist, It Doesn't Point To a Valid Object. You Must Create An Object An Assign It To Mylist Before You CAN Access Any Of It's Methods or Properties. In Delphi, Unlike C , An Object's Constructor Allocates It's OWN Memory, And You Must Explicitly Call The Constructor: MyList: = TList.create; MyButton : = TButton.create (Self); This Is Equivalent to the Following C Statements: MYLIST = New TList; MyButton = New TButton (this); When you finish Using The Object, You Must Explicitly DEAllocate It's Memory By Calling The Object's "Free" Method. "free" Is Not The Object's Destructor; That One is Typically Called "Destroy"; But "free" calls "Destroy" after Performing Certain Checks. A Programmer Would Normally Redefine "Destroy", But Call "Free". Mylist.free; mybutton.free; This is the equivalent of using "delete" on Objects in C : DELET E MYList; delete Mybutton; But Wait! Isn't Mylist a Pointer? Shouldn't it has to be dereferenced before Calling free or any of it's methods? Yes, IT SHOULD, But Object Pointers Are Different from Regular Pointers. They don't need Dereferencing (in Fact, They Don't allow it). This Makes for a Simpler Syntax, And Code That's A Lot Easier To read and maintain. Virtual and Override Just Like C , Object Pascal Has Virtual Methods (in Fact It Has Several Kinds of Virtual Methods). A Method Is Defined As Such With the keyword "virtual". The Difference Here Is this by You Redefine a Virtual Method You Have to Use the "Override" Directive. if you don't, the New Method Will Just Hide The Old One, As if IT WAS Static. for example: For The Base Class Tmybase: TMYBASE = Class {Declare a Virtual Method } Procedur e Mymethod (Arg1 : Integer; Virtual; Procedur E Mycaller; end; Procedure TMYBASE.MYMEMETHOD (arg1: integer); begin {Write the name of the class plus arg1 } WriteLn ('TMYBASE [' INTTOSTR (Arg1) ']'); END; Proce Dure TMYBASE.MYCALLER; Begin < / font> mymethod (1); When You Call Tmybase.mycaller, You get: 'TMYBASE [1]'. In a class deived from tmybase, the method "MyMethod & Q UOT; Can Be Overridden Like this: TMYCHILD = Class (TMYBASE) {Override the Virtual Method } Procedur e Mymethod; OVERRIDE; END; Procedure TmyChild.Mymethod (arg1: integer); begin {Write the name of the class plus arg1 } / TT> Writeln ('TMYCHILD [' INTTOSTR (Arg1) ']'); END; Now, when you call tmychild.mycaller, You'll Get: 'TmyChild [1]' A Hassle You Say? Maybe. But it gives you the flexibility of deciding WHETHER Or not to override the Virtual method. if you do this instead: TMYCHILD = Class (TMYBASE) {Don't Override The Virtual Method } Procedur e Mymethod (arg1: integer); Procedure TmyChild.Mymethod (arg1: integer); begin {Write the name of the class plus arg1 } / TT> Writeln ('TMYCHILD [' INTSTR (Arg1) ']'); END; "MyMethod" Will BE Treated (for polymorphic purposes) As if The Original Definition Was Static. When You Call TmyChild.mycaller, You'll get: 'TMYBASE [1]'. You can not, by the Way, Override a static method. Invoking redefined Methods You can use "inherited" to call the Most Recent Version of An inherited method, EVEN if it is being redined or overridden in the current Class. However, if you need to call an older version of the method, you are out Of Luck. Procedure < Strong> TMYCLASS.MYMETHOD (arg1: integer); Begin < / font> { Call the inherited virtual measure } Inherite d Mymethod (arg1); {call a Different Inherited Method } Inherite d OtherMethod;> End; INSIDE An Event Handler, You are allowed to call the networkler without Knowing it's name. You do this by calling "inherited" all by itself. {Event Handler. You ONLY NEED THE KEYWORD } Procedure Wmpaint (VAR Msg:> tMessage; < Strong> Begin < / font> ... Inherite D; ... END; Inherited Constructionors and Destructors One of The Greatest Sources of Bugs for C Programmmers Moving to Delphi IS Forgetting to Call inherited Constructors and destructors explicitly. Derived Class Constructors In C Can Explicitly Indicate Which Base Class Constructor to Call, But The Compiler Will Automatical Call The Base Class' DEFAULT CONSTRUCTOR IF NONE IS Specified. for this Reason, IT IS VERY Common To Do this IN C : TMYCLASS :: TmyClass {// your code he}; INSTEAD OF: TMYCLASS :: TMYCLASS: TMYBASE {// Your code Here}; HOWEVER IN Object Pascal, IF you redefine a Constructor, You Mustexplicitly Call The inherited constructor. All classes have at Least One Inherited Constructor and Destructor (The ones inherited from Tobject). Const Ructor TMYCLASS.CREATE; Begin < / font> { Call the base class'} {constructor explicitly } inherite d Create; {Your Code Here } This Would Be The Same As The Following C Construct: TMYCLASS :: TmyClass; {/ / Call the constructor of this // Object's base class explicitly t Mybase :: Tmybase; / / Your code he}; Do Not Attempt to Use A Similar Syntax with Object Pascal. While The Program Would Compile, The Logic Would Be WRONG: Const Ructor TMYCLASS.CREATE; Begin < / font> { This is not what you evpect } TMYBASE.CREATE; {Your Code Here } END; This Constructor is indeed calling the constructor for the base class, but it Is Just Creating An Independent Object of Type Tmybase. This Does Not Allocate Memory for the Current Object, Nor Does IT ITIZE IT. THE CALL TO The inherited constructor is generally the first Statement in A Constructor. this is not a syntax request; you can call class methods and Non-Member Functions and You CAN Access Local, Global Or Modular Variables First; But if you try to access any of the class' data elements or methods Before calling the inherited constructor, you'll get a recognor protection Fault. As Sneaky As This Error Can Be, It's Nothing Compared to What happens when You forget to call the inherited destructor. with the constructor, you at least Get a gpf this tells you where the error occurred. with the destructor however, your problem is more difficult to detect: you just start running out of memory. Depending On your Program, You May Notice Performance Degradations, Inain To Allocate Memory, Running Out of Windows Resources, Locked Devices OR Files, ETC. To Prevent this from happensing, always call the inherited destructor. This is USUALLY DONE AT THE End of the New Destructor (But Again, this is not a SyntActical Requirement: DESTR Uctor TMYCLASS.DESTROY; Begin < / font> { Your code here } Inherite d DESTROY; One Other Thing About Destructors: Remember To "OVERRIDE>" Them. The "free" Method Won't find your NEW DESTRUCTOR if you don't. Neglecting this is just as bad as forgetting to Call the inherited destructor. Multiple Constructors Since there is no overloading in Object Pascal, you might be wondering how You Can Have Multiple Constructors. The answer to this is very simple: the old Fashioned WAY! You Can Have As Many Constructors as you want, provided they each has DiffERENT NAME. While In C All Constructors Have The Same Name As The Class, In Object Pascal They Are Generally Called "Create". this is not a required, Just A Standard. if you need extra constructors, you generally use the word "Create" with something else. For example: Constructor> CreateCopy; Constructor Createaschild (iParent: TOBJECT); Constructor CreateFromFile (ifilename: string); You can only override a constructor with another That Has The Same Name and Parameter List (Even the Argument Names Are Important). if you only match the Constructor's name, You'll Only Be "Hiding" The inherited constructor.if you are developing a Visual Control, Keep In Mind That All Controls Must Have a Constructionor Declared Like this: Const Ructor Create (Aowner: Tcomponent); OVERRIDE; IF you omit this declaration, delphi won't be able to instantiate your CONTROL. Common base Class Every Object Created in Delphi is a descendant of tobject. If you don't specify a base class when declying your class, Delphi Derives IT From Tobject Anyway. All Components Are Derived from Tcomponent (Which of Course, Derives from TOBJECT, And All Controls Are Derived from TControl (Which is in turn derived from Tcomponent, ETC. The Importance of this Fact IS That It Gives The Visual Component Library A Great Advantage Over C Class Libraries Like Owl and MFC. Since All Objects Have A Common Ancestor, You Create Container Classes That Can Take Any Kind Of Object, (or Components Only, or Controls Only, etc.) Neatly Doing Away with One of the main reasons for requiring templates. The Self Pointer The "self" Pointer Is Object Pascal's Equivalent to C 'S "this" Pointer. They are except In. WHEN USED WITHIN a class method, self refers to the Class and not to the object (the instance). this hardly Ever Matters, Since Class Methods Are Very Rare, And You Can't Do A Great Deal in Them Anyway. Class Methods Class Methods Are Me MEMBER FUNCES or Procedures That Act ON A Class Instead Of an instance of a class. You Can Call a Class Method in The Regular Manner, But You Can Also Call IT WITHOUT HAVING An Object Instance. this is done by prepending the class name Instead of the name of an instance. a class method's "self" Pointer Refers to aclass instead of an object. IF you want to turn a method Into a class method, you just prepend the word "Class" to it's declaration (and definition). The Compiler Will NOT LET You Access Any Data Elements Or Regular Methods from Withnin A Class Method.you CAN Declare Local Variables Though. AN EXAMPLE OF A Class Method IS The getclassname function: Class Function TMYCLASS.GETCLASSNAME < / strong>: String; Begin Result: = 'TMYCLASS'; END; Constructors Are A Special Kind of Class Method. The Constructor's "Self" Pointer Is A Regular Object Pointer, Not a class Reference; and you can access Data Elements from With (Just Make Sure You Call That Inherited Construction) First). MEMBER Visibility and "Friends" IN C We Are Used to the keywords: "public", "private" and "protected". These is present In Object Pascal As Well, But They Work A Little Different. "Public" Works as expertted, but "private" and "Protected" Have No Effect On On Other Classes Declared With The Same Unit. in Other Words, All The Classes Declared in The Same Unit Are Friends with each other. this is important, Since there is no "Friend" Keyword in Delphi. Delphi Also Has A "Published" Keyword Which Behaves Almost Exactly Like "Public", But you Won't need to use it it unless you Want to create Your Own Controls. Since there is nothing Similar in C , The "Published" Keyword Is Beyond The Scope of this text. The scope Resolution Operator C HAS The double-colon ("::"), but object Pascal, HAS No Separate Scope resolution operator.instead, The dot (".") Serves Multiple Duty. WE Already Know That That Dot IS Used In Method Declarations, and for Accessing Methods, Properties and Data Members. But when's a name conflict Between A Stand-Alone Function or Procedure and a class method, you can precede The Function Call with the name of the unit what contains the function and a DOT: Language Syntax C = :: Object Pascal : = As Discussed Earlier, you can not use the dot notation to call an inherited Method, for this you will use the keyword "inherited < / strong> ". Other Syntax Elements Here Are Some Relatively Trivial Items That Can Be Annoying To C Programmers. THE Assignment Operator Remember "=" is for Comparison and ": =" is for Assignment. You will offten find yourself Using C 's Operators. No Big DEAL, THE Compiler Will Catch The Error, Because Pascal Doesn't Allow The Use of The Assignment Operator in Evaluation Expressions, Nor Does It Permit Chained Assignments. The else> Clause The Statement Preceding An "Else" Must Never End in A SEMICOLON. You will probably always forget this. Even seasoned Pascal Programmers Forget It. The Compiler Will Catch IT, But it's rather annoying. Incrementing and Decrementing Values IN C , THE " & Q UOT ;, "-", " =" - = "Operators Are A Very Useful (and fast) shorthand. in Delphi, There is Elegant, Equivalents: "inc" and "dec". C Pascal code> Shortcuts td> > <> color = "# 000000"> a; A ; A: = a 1; INC (A); -> <> color = "# 000000"> a; A -; A: = a - 1; Dec (a); A = 2; A: = a 2; INC (a, 2); A - = 2; A: = a - 2; DEC (a, 2); Although Inc and Dec Love Like Regular Procedures, The Fact That They Can Have ONE or Two Parameters Gives US A Hint That They Are Not (There's NO Overloading in pascal). in Fact, The Compiler Generates More Efficient Code for The THAN for the regular assignment-and-addition or assignment-and-subtraction. Inc and Dec Are Not Exact Equivalents for " " and "-" Operators. Since the isy Procedures, NOT functions, they don't return a value, so the can't be used in EXPRESSIONS. - Your Buddha Mercy ※ Source:. The Big Greenwwn.du. [From: 129.170.66.196] ※ Modified:. Mars at Jul 27 01:38:43 Modify this article. [From: thayer66-bp-196.]
end;