Board index » Visual Studio » Understanding C code...

Understanding C code...

Visual Studio240
Can anybody help me to translate the following lines to pascal(delphi)?



Let me explain what I'm looking for:



int i = 1; {In this line, an integer variable which is called "i" is

declared and it is initialised with 1}





BYTE data[2000]={0};

BITMAPINFOHEADER *bh=(BITMAPINFOHEADER*)data;

RGBQUAD *pal=(RGBQUAD*)(data+sizeof(*bh));





I am very confused with the meaning that has the * in C/C++

I don't understand why it precedes the variable/type in some cases and in

other cases it is later

Neither I understand this kind of lines:



(BITMAPINFO*)bh {a type cast?}

&specbuf {the data referenced by a Pointer variable?}



Thanks in advance, and have a Happy New Year.

Julian Maisano - LP - ARG


-
 

Re:Understanding C code...

"Julian Maisano" <maisanosys@yahoo.com>wrote in message

Quote
Can anybody help me to translate the following lines to

pascal(delphi)?



I think you need to look at a C (or C++) textbook since there are lots of

details that can trip you up in different examples. Pointer syntax is one of

the trickiest parts of C/C++.



Nevertheless, I will have a go:



Quote


Let me explain what I'm looking for:



int i = 1; {In this line, an integer variable which is called "i"

is declared and it is initialised with 1}





BYTE data[2000]={0};



An array called data, comprising 2000 components of type BYTE, with each

component initialised to equal zero.



Quote
BITMAPINFOHEADER *bh=(BITMAPINFOHEADER*)data;



On the left-hand side (LHS) is a pointer called bh, which points to a

BITMAPINFOHEADER structure. On the right-hand side (RHS) is the data

variable encountered previously, which is "cast" to a variable of type

"pointer to BITMAPINFOHEADER", i.e., the RHS is cast to the same type as the

LHS.



data is an array, but there is a built in conversion that converts an array

name into a pointer to the first element of the array. Thus data can be

automatically converted to "pointer to BYTE" and this "pointer to BYTE" is

cast to a "pointer to BITMAPINFOHEADER".



Quote
RGBQUAD *pal=(RGBQUAD*)(data+sizeof(*bh));



On the LHS, pal is a pointer to a RGBQUAD structure. On the RHS, data is

converted to a pointer, which stores a memory address, and the value

sizeof(*bh) is added to the address in order to give a later address. Thus

you end up with a pointer to a later address, which is cast to a pointer to

RGBQUAD.



In the expression sizeof(*bf), *bf refers to the BITMAPINFOHEADER structure

that bf points to. This is the most confusing part of pointer syntax. To

explain further, * is the dereferencing operator. When the dereferencing

operator is applied to a pointer, the result is the object pointed to.

Observe now that the general format for variable declaration is



typename variablename;



Thus in the definition



BITMAPINFOHEADER *bh=(BITMAPINFOHEADER*)data;



you can look at the LHS in either of two ways:



1) BITMAPINFOHEADER is the typename and *bh is the variablename. This says

that *bh is a BITMAPINFOHEADER, which must mean that bh is a pointer to

BITMAPINFOHEADER.



2) BITMAPINFOHEADER * is the typename (i.e., the typename is "pointer to

BITMAPINFOHEADER") and bh is the variablename. Once again, this means that

bh is a pointer to BITMAPINFOHEADER.



What makes this extra tricky is that it is only when a pointer is

initialised at the time of declaration that



*bh = ???



will make an assignment to the pointer. At any other time



*bh = ???



will make an assignment to the BITMAPINFOHEADER object that bh points to.

Thus the RHS will not be a pointer, it will be another BITMAPINFOHEADER

object. To make an assignment to the pointer, you simply use



bh = ???





Quote


I am very confused with the meaning that has the * in C/C++

I don't understand why it precedes the variable/type in some cases

and in other cases it is later



* follows type names (char, int, RGBQUAD, BITMAPINFOHEADER) and precedes

variable names (bh, pal).



Quote
Neither I understand this kind of lines:



(BITMAPINFO*)bh {a type cast?}



Yes, a type cast.



Quote
&specbuf {the data referenced by a Pointer variable?}





If this is C (and not C++), then & is the "address of" operator. &specbuf

gives the address in memory of the specbuf variable.





--

John Carson

1. To reply to email address, remove donald

2. Don't reply to email address (post here instead)





-

Re:Understanding C code...

"Julian Maisano" <maisanosys@yahoo.com>wrote:

Quote


Can anybody help me to translate the following lines to pascal(delphi)?



Let me explain what I'm looking for:



int i = 1; {In this line, an integer variable which is called "i" is

declared and it is initialised with 1}



BYTE data[2000]={0};

BITMAPINFOHEADER *bh=(BITMAPINFOHEADER*)data;

RGBQUAD *pal=(RGBQUAD*)(data+sizeof(*bh));



I am very confused with the meaning that has the * in C/C++

I don't understand why it precedes the variable/type in some cases and in

other cases it is later



You shouldn't be confused; * in C is very similar to the ^ operator in

Pascal. Both are overloaded, and used both to create a pointer TYPE, and

to dereference a pointer VARIABLE.



type

PINT = integer^;



var

i: integer;

pi: PINT;



begin

i := pi^;

end;



This is very similar to this C code:



typedef int * PINT;

int i;

PINT pi;



i = *pi;





Quote
Neither I understand this kind of lines:



(BITMAPINFO*)bh {a type cast?}



Yes, exactly.



Quote
&specbuf {the data referenced by a Pointer variable?}



"&" is the "address of" operator. "*" is the "dereference" operator.

They are, in some sense, opposites.



Quote
BYTE data[2000]={0};

BITMAPINFOHEADER *bh=(BITMAPINFOHEADER*)data;

RGBQUAD *pal=(RGBQUAD*)(data+sizeof(*bh));



Delphi includes these types directly, and even a C-like cast operator, so

this should work. BTW, there are many examples of DIB code in the Delphi

standard library code. Search for BITMAPINFOHEADER.



var

data: array[0..1999] of byte;

bh: PBITMAPINFOHEADER;

pal: PRGBQUAD;

begin

bh := (PBITMAPINFOHEADER)@data;

pal := (PRGBQUAD)(Pointer(data)+sizeof(BITMAPINFOHEADER));

...

--

- Tim Roberts, timr@probo.com

Providenza & Boekelheide, Inc

-

Re:Understanding C code...

Hello,



procedure test1;

type

PBITMAPINFOHEADER = ^BITMAPINFOHEADER;

BITMAPINFOHEADER = record

// fill def here

end;



PRGBQUAD = ^RGBQUAD;

RGBQUAD = record

// fill def here

end;



var

data: array[1..2000] of byte;

bh: PBITMAPINFOHEADER;

pal: PRGBQUAD;

begin

//BYTE data[2000]={0};

FillChar(data, sizeof(data), 0);

// BITMAPINFOHEADER *bh=(BITMAPINFOHEADER*)data;

bh := PBITMAPINFOHEADER(@data);

// RGBQUAD *pal=(RGBQUAD*)(data+sizeof(*bh));

pal:= PRGBQUAD(Dword(@data)+sizeof(BITMAPINFOHEADER));

end;



"Julian Maisano" <maisanosys@yahoo.com>wrote in message

Quote
Can anybody help me to translate the following lines to pascal(delphi)?



Let me explain what I'm looking for:



int i = 1; {In this line, an integer variable which is called "i" is

declared and it is initialised with 1}





BYTE data[2000]={0};

BITMAPINFOHEADER *bh=(BITMAPINFOHEADER*)data;

RGBQUAD *pal=(RGBQUAD*)(data+sizeof(*bh));





I am very confused with the meaning that has the * in C/C++

I don't understand why it precedes the variable/type in some cases and in

other cases it is later

Neither I understand this kind of lines:



(BITMAPINFO*)bh {a type cast?}

Its pascal equivalent is: PMyStruct(bh)



Quote
&specbuf {the data referenced by a Pointer variable?}

Its pascal equivalent is the '@' operator.



Quote


Thanks in advance, and have a Happy New Year.

Julian Maisano - LP - ARG





-

Re:Understanding C code...



"John Carson" <donaldquixote@datafast.net.au>wrote in message

Quote
>

>BYTE data[2000]={0};



An array called data, comprising 2000 components of type BYTE, with each

component initialised to equal zero.





According to other replies (comp.lang.c++) only the first element of the

data array is initialized with the given value:



Byte data[2000]={5}



data[0] == 5 {true}

data[1] == 5 {false}

data[1] == 0 {true}



happens the same with microsoft compilers?











-

Re:Understanding C code...

Hi Julian,



All other elements in VC6 compiler result in zeroed out values, so in your

example, data[1] contains zero. Though I've no proof, I would venture to

guess that this is covered by a standard; and so is not a compiler-specific

thing. Stroustrup in section 5.2.1 (Array Initializers) states "If the

initializer supplies too few elements, 0 is assumed for the remaining vector

elements".



Regards,

Mike





"Julian Maisano" <maisanosys@yahoo.com>wrote in message

Quote


"John Carson" <donaldquixote@datafast.net.au>wrote in message

>>

>>BYTE data[2000]={0};

>

>An array called data, comprising 2000 components of type BYTE, with each

>component initialised to equal zero.

>



According to other replies (comp.lang.c++) only the first element of the

data array is initialized with the given value:



Byte data[2000]={5}



data[0] == 5 {true}

data[1] == 5 {false}

data[1] == 0 {true}



happens the same with microsoft compilers?















-

Re:Understanding C code...

"Julian Maisano" <maisanosys@yahoo.com>wrote in message

Quote
"John Carson" <donaldquixote@datafast.net.au>wrote in message

>>

>>BYTE data[2000]={0};

>

>An array called data, comprising 2000 components of type BYTE, with

>each component initialised to equal zero.

>



According to other replies (comp.lang.c++) only the first element of

the data array is initialized with the given value:



Byte data[2000]={5}



data[0] == 5 {true}

data[1] == 5 {false}

data[1] == 0 {true}



happens the same with microsoft compilers?





At least in C++, the position is clear and is as Mike suggests. The

components that are not explicitly initialised are initialised to zero. Thus



BYTE data[2000] = {0};



will initialise all elements to zero, as originally stated. Your code should

initialise every component to zero except for the first. If data[1]==5, then

this is wrong according to the C++ standard. I don't have access to the C

standard, so I am not sure what it says on the subject.



The matter is covered in the C++ standard in section 8.5. First we have the

definition of "default-initialisation":



"To default-initialize an object of type T means:

- if T is a non-POD class type (clause 9), the default constructor for T is

called (and the initialization is

ill-formed if T has no accessible default constructor);

- if T is an array type, each element is default-initialized;

- otherwise, the storage for the object is zero-initialized."



Next we have the definition of an "aggregate".



"An aggregate is an array or a class (clause 9) with no user-declared

constructors (12.1), no private or pro-tected

non-static data members (clause 11), no base classes (clause 10), and no

virtual functions (10.3)."



Finally, we have the relevant rules on the default intialisation of an

aggregate:



"If there are fewer initializers in the list than there are members in the

aggregate, then each member not

explicitly initialized shall be default-initialized (8.5).

[Example:

struct S { int a; char* b; int c; };

S ss = { 1, "asdf" };

initializes ss.a with 1, ss.b with "asdf", and ss.c with the value of an

expression of the form

int(), that is, 0. ]"







--

John Carson

1. To reply to email address, remove donald

2. Don't reply to email address (post here instead)



-

Re:Understanding C code...



"Julian Maisano" <maisanosys@yahoo.com>wrote in message news:e9paun$zDHA.3220@tk2msftngp13.phx.gbl...

Quote


"John Carson" <donaldquixote@datafast.net.au>wrote in message

>>

>>BYTE data[2000]={0};

>

>An array called data, comprising 2000 components of type BYTE, with each

>component initialised to equal zero.

>



According to other replies (comp.lang.c++) only the first element of the

data array is initialized with the given value:





The elements of the array not given initializers are DEFAULT INITIALIZED.

In the case of char, that means set to zero.



-

Re:Understanding C code...



"Michael T. Pudelko" <->wrote in message news:esgSXDA0DHA.2580@TK2MSFTNGP09.phx.gbl...

Quote
"If the

initializer supplies too few elements, 0 is assumed for the remaining vector

elements".



Specifically, the elements not provided initializers are DEFAULT INITIALIZED.

For numerics (and other POD's) that's zero initialization.



-

Re:Understanding C code...



"John Carson" <donaldquixote@datafast.net.au>wrote in message

Quote
At least in C++, the position is clear and is as Mike suggests. The

components that are not explicitly initialised are initialised to zero.

Thus



BYTE data[2000] = {0};



will initialise all elements to zero, as originally stated. Your code

should

initialise every component to zero except for the first. If data[1]==5,

then

this is wrong according to the C++ standard. I don't have access to the C

standard, so I am not sure what it says on the subject.



If there are fewer initializers in the list than there are members in the

aggregate, then each member not

explicitly initialized shall be default-initialized



Ergo

= {0}; is redundant





Am I correct?















-

Re:Understanding C code...



"Julian Maisano" <maisanosys@yahoo.com>wrote in message

Quote


Ergo

= {0}; is redundant





Am I correct?





I mean...

Why to tell the comiler "Initialize the first element to 0" if even without

this initialization, the entire array will be initialized with 0?



so

={0}

={0,0,0}

Are redundant



but

={5}

={4, 10, 9}

Aren't











-

Re:Understanding C code...



"Julian Maisano" <maisanosys@yahoo.com>wrote in message news:OMcF85M0DHA.1336@TK2MSFTNGP12.phx.gbl...

Quote
>If there are fewer initializers in the list than there are members in the

>aggregate, then each member not

>explicitly initialized shall be default-initialized



Ergo

= {0}; is redundant





Am I correct?



Unfortunately, you are NOT. Depending on where the aggregate is defined it

may not be redundant. It is a major defect in C++ that default initialization of

certain (POD) types is omitted under certain circumstances. The = { 0 } initializer

forces the aggregate to be initialized in these cases.



-

Re:Understanding C code...



"Julian Maisano" <maisanosys@yahoo.com>wrote in message news:O1guHHN0DHA.1304@TK2MSFTNGP10.phx.gbl...

Quote


"Julian Maisano" <maisanosys@yahoo.com>wrote in message

>

>Ergo

>= {0}; is redundant

>

>

>Am I correct?

>



I mean...

Why to tell the comiler "Initialize the first element to 0" if even without

this initialization, the entire array will be initialized with 0?



No, in the case of automatic (i.e., local to function/block) variables,

the initialization is omitted entirely (default initialization does not occur).



void foo() {

int a[5]; //uninitialized;

int b[5] = { 0 }; // all 5 initialized to zero.

}



-