Duoas 1,025 Postaholic Featured Poster

The swap function is provided for backwards compatibility only. It cannot handle integer/cardinal sized types. It can only handle smallint/word (16-bit) values.

You might want to write your own versions of swap.

Duoas 1,025 Postaholic Featured Poster

Take a look through this thread:
Tutorial: Handling Dates and Time in Delphi

Near the bottom there is some thoughts on reading dates (which is the hard part). Writing dates is easy.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

1. Search the forum.
2. Think about it some.

Quoted for agreement.

Not to be a jerk, but just give it a try and see what you get. When you have problems show us what you have tried and we'll help you.

All that said, I think that the easiest way would be to use 10 same-sized bitmaps (that you can draw yourselves in Paint) and a TImageList component.

Duoas 1,025 Postaholic Featured Poster

1. Search the forum.
2. Think about it some.

Good luck.

Duoas 1,025 Postaholic Featured Poster

That's my thought exactly. I just can't figure out what BDS is doing... But I'll take a look at the GDI+.

I'm wondering if BDS is doing some sort of in-memory modification of one of the shared DLL's? (But that makes no sense either, because each process gets its own copy...) Is isn't overclocking my CPU or anything... aarrrrrghhhh.

I've also compiled with RtlVclOptimize.pas and I'm considering adding FastCode also...

Duoas 1,025 Postaholic Featured Poster

Ah, a 1D list. OK.

If you are at liberty to create your own input file, I suggest you make it something easy to read (programmatically), like:

0 12 0 2
1 24 0 2
2 13 1

where the first number on the line is the node number, the second is its weight, and any remaining are edges leaving the node. (You don't actually have to list the node number, you could just deduce it from the line number as you read...)

Make yourself a record that represents a node. Then use an array of that record type. All you have to do then is read one line at a time into one node at a time.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Use a 2D array or a sparse matrix.

How do you plan to use the graph?

Duoas 1,025 Postaholic Featured Poster

Thanks for the info. That Process Explorer is slick.

Alas, I don't really know what I am looking for. As far as I can tell, my application and BDS don't share anything... (except some non-relocated kernel DLLS).

Other than that, all I know at this point is that my application runs more than twice as fast when BDS is in memory than when it is not.

The following behavior might be of interest:
1. Start BDS, then my app. Stop BDS. My app stays fast. Restart my app and it is slow again.

2. Start my app, then BDS. Stop BDS. My app becomes slow again.

3. BDS is always fast.

Arrgh!

Duoas 1,025 Postaholic Featured Poster

No such thing exists.

The Lazarus IDE itself has an 'import project' item. You might want to look through the FPC Lazarus For Delphi Users page.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

It is a common idiom. Each bit represents one flag. The flags are named (like CS_DBLCLKS == permit the window to receive double-click events). Simply OR together the ones you want.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

The problem is here: Procedure addEmployee( position:integer;var employee:WorkT); and here: 1: addemployee(position, employee); The addEmployee procedure increments its local position variable, but it does not change the global position variable. There are two ways to fix this:

1. Procedure addEmployee( [B]var[/B] position:integer;var employee:WorkT); 2.

1: begin
   inc( position );
   addEmployee( position, employee )
   end;

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Your friend left out for statements...

If your Pascal program does not contain any looping constructs (loops, gotos, and recursion), then the halting problem is valid only if the program and/or the input is infinite.

To consider why, think about how a Turing machine's transitions are represented. Without loops, the transitions can never return to a node already visited. Hence, if such a program is finite, it must eventually stop.

Pascal has some implicit loops in routines like readln, etc. so even if the program is finite, if the input is infinite then it may never end.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Hey, thanks for the reply.

No, I haven't used the control panel. I've directly timed it as: (number of paint events)/(milliseconds elapsed) while scrolling.

The point is that my executable is not modified in any way between testing with BDS running and testing without BDS running. Yet, my executable performs better when BDS is running.

Which means to me that BDS must be doing something either to the system or to the in-memory libraries common to both my application and BDS to make things faster. I can't figure out what that is though...

Duoas 1,025 Postaholic Featured Poster

Yep, you are right. It is entirely new.

The most significant help will be to keep in mind that Windows was written in C, not C++.

WINAPI is a #define for the stdcall calling convention modifier. By explicitly defining the function as using the stdcall calling convention, you are free to use any other you wish in your program and still be able to call the windows API functions without any problems.

The & is indeed the "address-of" operator. Win API functions don't take pass-by-reference arguments; only pointer and value.

A window class is a set of properties for one or more windows, like background brush, mouse cursor, does it have a drop shadow, what buttons are displayed on the titlebar, or even if it has a titlebar, etc. Here the term "class" is used in its generic sense, not in the C++ sense.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

I'm sorry ... I didn't pay enough attention to the question.

You should set the label's Caption property, not Text.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Since this is the C++ forum, why don't you just dump sprintf() and use the standard streams?

#include <string>
#include <sstream>

int main()
{
  double b = 3.0000;
  std::string s;

  // convert double b to string s
  { std::ostringstream ss;
    ss << b;
    s = ss.str();
  }

  // do something here with s
}

The extra { } make the stringstream variable a temporary -- after you do the conversion ss doesn't exist anymore.

The advantage of using the standard streams is that you get much more flexibility when deciding how to format your output.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

There are two easy ways:

1. Use ShowMessage( char * )
This puts up a little dialogue box with your text and an OK button. It causes your application to pause until the user clicks OK.

2. If time is an issue, then call AllocConsole() somewhere at the beginning of your program (in main() or in your form's constructor, etc). Thereafter you can use cin and cout as usual.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Hi Jennifer.

You can use the fill algorithm:

#include <algorithm>
#include <vector>

int main()
{
  std::vector<int> Numbers( 5000, 42 );  // 5,000 '42's.
  std::fill(
    Numbers.begin(),
    Numbers.end(),
    0  // Turn them '42's into '0's
    );
}

Now, if you really are using a vector of vectors (5000 * 5000 elements), you can use the transform() algorithm to better success.

#include <algorithm>
#include <vector>

std::vector<int> fill_zero( std::vector<int> v )
{
  std::fill( v.begin(), v.end(), 0 );
  return v;
}

int main()
{
  // 25,000 '42's in a square matrix
  std::vector<std::vector<int> > Numbers(5000, std::vector<int>(5000, 42));

  // Turn them all to zeros
  std::transform(
    Numbers.begin(),  // what to read
    Numbers.end(),    // when to stop reading
    Numbers.begin(),  // where to put the results
    fill_zero
    );
}

You'll notice that you can stick the results back into the same vector. You don't have to, though.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

A parameter is a temporary variable created by your routine. For example:

void bigger_than_five( int number )
{
  result = (number > 5);
}

In this example, number is the parameter (variable).

int main()
{
  if (bigger_than_five( 42 )) std::cout << "42 is bigger than 5\n";
  else std::cout << "hmm... 42 is not bigger than 5 !\n";
}

In this example, 42 is the argument or value we give to the variable 'number'.

The only place that the variable number exists is inside the function bigger_than_five(). Hence, the following is an error:

int main()
{
  number = 42;  // error, 'number' doesn't exist!
  if (bigger_than_five( number )) std::cout << "blah blah blah\n";
}

I hope this helps.

[edit] Yoinks! I'm slow...

Duoas 1,025 Postaholic Featured Poster

Hi all.

I'm writing a little program that paints and animates its own form in response to the user's mouse gestures. The weird thing is:

Whenever the BDS Delphi 2006 is running and I run my application, I get a framerate of about 25 FPS. If I terminate BDS but not my application the framerate stays high.

However, if I then restart my application when BDS is not running my application runs at about 11 FPS. This is without any change to the code or executable. (This also seems to me to be a little backwards... alas.)

I've recompiled my app using Delphi 5 and it still gets the slow framerate. My only conclusion is that BDS is doing something to the system or loading some Borland/Codegear shared module that is bumping performance?


In short, does anyone know why this is happening? And where I should look to make my application get the higher framerate?

Thanks

Duoas 1,025 Postaholic Featured Poster

Delphi IDEs aren't too fond of compiling units by themselves.

What you need to do is:

  1. start Delphi
  2. create a new project
  3. from the main menu select Project->Add to Project
  4. select the UIRT.pas file
  5. from the main menu select Project->Build All

You can then just get the UIRT.dcu file out of the project directory.

Good luck.

Duoas 1,025 Postaholic Featured Poster

An EAbstractError occurs whenever an abstract method is called. For example:

type
  // This is an abstract class
  tAbstract = class
    public
      procedure overrideMe; virtual;
    end;

  // This is also an abstract class
  tStillAbstract = class( tAbstract ) end;

  // However, this is not, since it provides methods
  // for all the ancestor's virtual/dynamic methods.
  tNotAbstract = class( tAbstract )
    public
      procedure overrideMe; override;
    end;

var
  fooey: tAbstract;

procedure tNotAbstract.overrideMe;
  begin
  showMessage( 'not abstract' )
  end;

begin
  // The following is error-free
  fooey := tNotAbstract.create;
  fooey.overrideMe;
  fooey.free;

  // The following raises EAbstractError
  fooey := tStillAbstract.create;
  fooey.overrideMe;
  fooey.free;
end.

Somewhere in your code you are

  1. Calling a method in an abstract class
  2. Not defining (overriding) an ancestor's virtual/dynamic (abstract) methods, which the existing software is trying to use.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

To determine which drives are available, their drive letters, and what kind of device they represent:

  • DWORD [b]GetLogicalDrives[/b]()
  • DWORD [b]GetLogicalDriveStrings[/b]( DWORD nBufferLength, LPTSTR lpBuffer )
  • UINT [B]GetDriveType[/B]( LPCTSTR lpRootPathName )

(Yes, the above is in C. Specify the Windows unit in your using clause to use them. Delphi will correct you about the types of the arguments as you type --chances are that the strings will be var parameters.) Either use the IDE help or Google MSDN for more information on each function.

To catch drive change notifications you need to subclass your main window. There are several ways to do this, but the simplest is just to override WndProc in one of your toplevel forms (probably the main form):

unit Unit1;
interface
uses ...
type
  TForm1 = class(TForm)
    ...
  protected
    procedure WndProc( var message: TMessage ); override;
  end;

implementation

procedure TForm1.WndProc( var message: TMessage );
  begin
  if message.msg = WM_DEVICECHANGE
    then case message.wParam of
           DBT_DEVICEARRIVAL: { A new drive is available };
           DBT_DEVICEQUERYREMOVE: { The user pressed the eject button. Allow? };
           DBT_DEVICEREMOVEPENDING: { The device is about to eject whether you like it or not. Clean up. };
           DBT_DEVICEREMOVECOMPLETE: { The device is no longer available. };
           end;
  inherited
  end;

The lParam contains a pointer to a DEV_BROADCAST_HDR record identifying the type of device. You'll have to query the system again to determine which device actually changed.

Google "msdn" and any of the above message constants for …

Duoas 1,025 Postaholic Featured Poster

I forgot to set the value of f_is_fullscreen in the code snippits. Don't forget to do that...:)

Duoas 1,025 Postaholic Featured Poster

To make a form fullscreen and restore it you will have to manipulate your form using a couple of Win32 API functions. #include <windows.h> First, you'll need some class variables to preserve your form's normal attributes when it is fullscreen. LONG f_form_style; WINDOWPLACEMENT f_form_placement; You'll also want to remember whether or not you are actually fullscreen. bool f_is_fullscreen = false; The following code snippit makes the window fullscreen. The variable handle is your form's hWnd.

WINDOWPLACEMENT wp;

  if (f_is_fullscreen) return;

  f_form_style = SetWindowLong( handle, GWL_STYLE, 0 );
  f_form_placement.length = sizeof( WINDOWPLACEMENT );
  GetWindowPlacement( handle, &f_form_placement );

  wp = f_form_placement;
  wp.showCmd = SW_SHOWMAXIMIZED;

  SetWindowPlacement( handle, &wp );

To restore the window:

SetWindowPlacement( handle, &f_form_placement );
  SetWindowLong( handle, GWL_STYLE, f_form_style );

As to the image, with Borland's TImage component, all you need to do is make sure that the AutoSize property is False and set the Stretch property to True. This will cause the image to stretch to fit the control's dimensions. That may distort it, so you will have to adjust the size of the control each time you assign a new bitmap to its Bitmap property to keep the aspect ratio correct.

So, if you have a form with a black or other neutral background with just a TImage on it, you can set the form to fullscreen. Then, to animate, just set a TTimer to assign the next image's bitmap to the form's TImage.picture.bitmap property, adjust the size so that at least two edges touch the …

Duoas 1,025 Postaholic Featured Poster

As far as I understand it (having rarely ever used VC++), a filter is MS's way of providing hooks into the application's main Window Procedure (which contains the top-level event loop) in order to process specific messages. Here's a useful page I googled.

You will need to use RegisterWindowMessage to define your special message, and then use the filter to catch it.

Hope this was what you were looking for.

Duoas 1,025 Postaholic Featured Poster

There's nothing wrong with BC++Builder...

What do you mean "make a TImage full screen"? Do you have an image you want to resize to your desktop? Or do you mean that you have a form and you want the image area to grow with the form when you maximize (like MSPaint's image area does)? Does the image have an actual picture in it that must be preserved?

Duoas 1,025 Postaholic Featured Poster

My thoughts exactly. Resource Hacker is a great little utility.

You should be aware, however, that playing around with another program's resources is not always safe. Well-written programs will handle changes gracefully, but those that make assumptions about their resource data may fail.

When you modify the bitmap, try to keep the same bitdepth and compression method (if any).

Good luck!

Duoas 1,025 Postaholic Featured Poster

It comes with time.

Sorry, for the error. I accidentally mixed C and Pascal. The line should read Timer1.Tag := n div 10; The "extended" is the IEEE 80-bit Extended Precision floating point type. Pascal converts single, double, and real to extended when performing calculations.

Duoas 1,025 Postaholic Featured Poster

What do you mean, "batches in the C language"?

Do you mean that you want to write a program that can process batch commands (like command.com or some other shell interpreter)?

Or do you mean that you just want to write scripts using C?

Duoas 1,025 Postaholic Featured Poster

Ack! I'm so sorry. I accidentally grabbed the wrong function... It's late and I've got to get some sleep but I'll post it early for you tomorrow.

atish00 The first is an STL header. The second comes with the Windows API.

Duoas 1,025 Postaholic Featured Poster

You need to turn off line buffering using SetConsoleMode. Here is an example function that does that to wait for the user to press a key:

#include <string>
#include <windows.h>

void console::pressanykey( std::string prompt ) {
  DWORD        mode;
  HANDLE       hStdIn;
  INPUT_RECORD inrec;
  DWORD        count;
  char         default_prompt[] = "Press the 'any' key...";

  /* Set the console mode to no-echo, raw input, */
  /* and no window or mouse events.              */
  hStdIn = GetStdHandle( STD_INPUT_HANDLE );
  if (hStdIn == INVALID_HANDLE_VALUE
  or !GetConsoleMode( hStdIn, &mode )
  or !SetConsoleMode( hStdIn, 0 ))
    return;

  if (prompt.empty()) prompt = default_prompt; 

  /* Instruct the user */
  WriteConsole(
    GetStdHandle( STD_OUTPUT_HANDLE ),
    prompt.c_str(),
    prompt.length(),
    &count,
    NULL
    );

  FlushConsoleInputBuffer( hStdIn );

  /* Wait for and get a single key PRESS */
  do ReadConsoleInput( hStdIn, &inrec, 1, &count );
  while ((inrec.EventType != KEY_EVENT) || !inrec.Event.KeyEvent.bKeyDown);

  /* Restore the original console mode */
  SetConsoleMode( hStdIn, mode );
  }

Google "msdn SetConsoleMode" for more.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

The check should be to prevent the user of the function from passing in a string that is too long to fit in st.n[] .

So:

/* Make sure the string is null-terminated */
  memset( (void *)C.n, '\0', sizeof(C.n) );

  /* Copy the string over, leaving room for null */
  strncpy( C.n, fe, sizeof(C.n) / sizeof(C.n[0]) );

This code makes use of a simple trick to have the compiler calculate the right constant values to use. The sizeof operator returns the number of bytes that an object uses.

memset() fills a specific number of bytes. So sizeof(C.n) is appropriate.

strncpy() copies a specific number of characters. To calculate the number of characters, we use sizeof(C.n) / sizeof(C.n[0]) , which is the same as (total number of bytes) / (bytes per element), which is the number of elements (or chars) in the array.

Whew.

Duoas 1,025 Postaholic Featured Poster

Sure. I use the Windows command prompt a lot, so I wrote a little batch file that I have set to be automatically executed whenever I start a command prompt.

I keep a lot of utilities in D:\bin\ , so I put the batch file there.

D:\bin\prompt.bat

@echo off
set path=d:\bin;%PATH%
set dircmd=/ogn
doskey >nul
doskey cp=copy $*
doskey lesss=less -S $*
doskey deltree=rd /s/q $*
doskey vi=notepad $*
doskey dird=dir /ad /d $*
doskey python=C:\PROGRA~1\Python25\python.exe $*
doskey pythonw=C:\PROGRA~1\Python25\pythonw.exe $*
echo on

For those 557 of you who have found my mpath program [ 1 ], you know that I like to keep my command path uncluttered with junk and programs not currently in use. That includes the GCC toolchain. So I made myself some little batch files to initialize it if it is not already in the command path. For example:

D:\bin\g++.bat

@mpath a C:\PROGRA~1\MinGW\bin
@"g++" %*

This adds the GCC toolchain to the head of my command path, so that the next time I type g++ at the command prompt the batch file doesn't get executed again. Then it starts the g++ as normal.

At the prompt, this is convenient because whenever I want to compile something, all I have to type is g++ something.cc and all the right stuff happens without my having to worry about first adding the GCC to my command path.

For other types of batch processing you'll have to give me an idea of …

Duoas 1,025 Postaholic Featured Poster

What OS are you using?

Duoas 1,025 Postaholic Featured Poster

A "batch" is a collection of things (data or jobs) to be dealt with by running a single program once.

Hence, a batch processor is a program that will handle batches.

A classic example is the old DOS command.com. Rather than type in a zillion commands each time you want to do something, you can put them all into a file (so you only have to type them once), then each time you want to use them again all you have to do is tell command.com to process that file. The commands you would have had to type are all executed and life is easy.

(All command shells that I know of do that. On Unix systems there is sh, csh, tcsh, bash, zsh, etc. It is usually referred to as shell scripting, since it is a little more advanced than simple batch processing.)

Another example is using a program like Irfanview (image viewer). Suppose you have a directory full of 2000 random-sized images and you would like to convert them all to 256 by 256 pixels. Rather than load, size, and save each file by hand, you can program Irfanview to perform the resize command over all the files in the directory. Thus you can save yourself many hours of work.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

For the constant lookup table, you first must know about a 7-segment display. Bit 0 is A, bit 1 is B, bit 2 is C, etc.

If you still can't get your head around that, don't worry about it. Just write ten separate procedures to display each digit.

The tough part is that you need a timer and an event loop. You can simulate them. Here is a little TP4 program that demonstrates it:

uses DOS, CRT;

procedure display( x: integer );
  { This routine draws whatever it is }
  { that you are displaying on the screen. }
  { In your case, it should update the 7- }
  { segment displays. }
  { (In my case, it just draws a silly number.) }
  begin
  gotoxy( 1, 1 );
  writeln( x );
  end;

function time: longint;
  { This routine returns the current time represented }
  { in hundredths of a second. In other words, 12:01 }
  { AM would be represented as 100. 12:02 as 200. Etc. }
  var h, m, s, s100: word;
  begin
  gettime( h, m, s, s100 );
  time := s100 +(s *100) +(m *600) +(h *600 *24)
  end;

var
  timeout: longint;
  i: integer;
  c: char;

begin
  { My 'i' variable is just to show the user that }
  { something is happening while waiting for a }
  { keypress. }
  { You will probably want to display the number }
  { of liters dispensed and the total cost so far. }
  i …
Duoas 1,025 Postaholic Featured Poster

Look, just for the record, I hate VB. But your opinion about it is just that: opinion. People like VB because it is less complicated to dink with than, say, C++. And platform dependence is not a valid argument against using a specific language to learn programming; it is only a valid argument against using a specific language when writing cross-platform code. As for strange and twisted: the language is, and has always been, straight-forward.

Duoas 1,025 Postaholic Featured Poster

You're using BP7, right?

I've googled a bit and it appears that BP7's WinCRT unit doesn't have those routines. Yes, I agree that's insane!

If you were just using the CRT unit I'd tell you to use the BIOS interrupts to set the output color, but I'm not sure what to do about the WinCRT routines...

Sorry. :S

Duoas 1,025 Postaholic Featured Poster

Link. Check out my post at the bottom.

(Sorry, I've got lazy fingers today.)

Ancient Dragon commented: Great solution -- I hadn't thought of that. :) +24
Duoas 1,025 Postaholic Featured Poster

Why not? VB is used all around the world for all kinds of enterprise-class applications.

Is there some concrete reason why it shouldn't be taught as an introductory language?

Duoas 1,025 Postaholic Featured Poster

Well, so far I have assumed that Word is an array of char pointers. char *Word[ 10 ]; If that is correct, then to swap you need something like:

char *swap;
...
// swapping part:
  swap = Word[j];
  Word[j] = Word[j+1];
  Word[j+1] = swap;

However, if your Word is a 2D array: char Word[ 10 ][ 100 ]; char swap[ 100 ]; then your swap should work fine.

Your bubble sort looks great.

To print the strings, use one of the following: puts( Word[z] ); printf( "%s\n", Word[z] ); Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Miranda has a lot of similarities to Haskell. I can't say for sure that I can help you, but post your question and we'll see.

Even if I can't, there are a lot of knowledgeable Haskell folks here that probably can.

Duoas 1,025 Postaholic Featured Poster

Use the TextColor and TextBackground procedures. The colors are defined as constants in the CRT unit: Black, Blue, Green, Cyan, etc.

If you plan to set the background color to DarkGray, LightBlue, etc. make sure to call HighVideo at the beginning of your program (so that your letters don't blink).

For example:

uses CRT;
begin
  HighVideo;
  TextBackground( White );
  TextColor( Black );
  ClrScr;
  GotoXY( 34, 12 );
  Write( 'Hello World!' );
  Readln
end.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Use strcmp() to compare the two strings. if (strcmp( words[j], words[k] ) < 0) { swap j and k } The strcmp() function is nice because the operator you use (less-than, equal-to, or greater-than) is exactly the same as it would be if you could put it between the strings like:

if (words[j] < words[k]) ...

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Make sure your form class looks something like this:

type
  TForm1 = class(TForm)
    ...
  public:
    { Public declarations }
    procedure sendNsecondsWorthOfBtoNotepad( n: integer );
  end;

...

implementation
{$R *.RES}

procedure Form1.sendNsecondsWorthOfBtoNotepad( n: integer );
  var ...
  begin
  ...
  end;

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

"Better" is a subjective word. If you mean in terms of "easier to use complicated code with fewer errors and improved error handling" then OOP is better.

Objects encapsulate information. That is to say, they don't just define related information, but they provide ways to manipulate that information.

One point of note: classes actually make life just a little bit more complicated for the people writing the class. The reward is that classes make life a breeze for people using the class. The tradeoff, however, is slim, since you'd generally have to write all the stuff that gets put in the class anyway, and when in a class it is much more coherent and easy to read.

The Before Way
For example, a non-object oriented thing is an array:

int xs[] = { 2, 3, 5, 7, 11, 13, 17, 19 };

If you want to print this array you have to know something "magical" about it: its length. The magical thing is that, given the array, there is no way to determine its length.

(Now, before those of you in-the-know respond with length = sizeof( xs ) / sizeof( x[0] ) I'll remind you that that only works because the compiler knows how long xs is. That only works in specific cases... when you are executing the program you cannot depend on the compiler's help.)

Suppose, for example, we have a little function to print that array:

void print_ints( int xs[] …
VernonDozier commented: Good writeup +1
Duoas 1,025 Postaholic Featured Poster

Let the flame wars begin.... sigh.

It doesn't really matter what language you choose to begin. You should be aware, however, that languages like lisp and scheme are functional, which is a different paradigm than imperative languages like C++ and VB. You have to use different parts of your brain to use them. (I like scheme.)

If you want to get really deep into games, you are best sticking with C++ or C.
If you don't need to go that far down the rabbit hole, you can pick what you like. There are SDL bindings for a lot of common languages, as well as other game toolkits for the stuff you like.

You might want to raise this question in the game forum for a more considered answer.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

I've got 2701 messages in my inbox. Email me at gmail. I'm michael.thomas.greer

Duoas 1,025 Postaholic Featured Poster

Every OS does that. When you link a DLL with your program one of the things that happens is there is a table of function pointers that gets initialized. Such things are essential in relocatable code.