January 30th, 2013, 04:17 PM
Structures and "." how they work
Hi to everybody.
Can someone explain me why or how does this work?--->
This looks strange to me because *ptr has a value which is 1
typedef struct test test;
(*ptr).d=100; //Here on this line why and how does this works.
//How C knows where to store 100?
Also do structures work on any way like arrays?
For example lets say we have
I know that the name of the array (arr in this case) stores the memory address of the first byte of the array
and by telling arr we mean go to the byte that is
on the memory address (arr + 4*sizeof(data type of the array))
(in words: go 4 chars down from the first one)
Well shouldnt the d(test type variable) from the first example store a memory address or something?
I know that in the current example
d has a value and it is 1(i think because of the line d.a=1; ) which is pretty strange to me.All i want at last is to learn
how exactly the member access operator actually internally works in C
and from that i hope to also understand how the line
(*ptr).d=100; actually works
January 30th, 2013, 05:51 PM
That code works because the struct d starts with its field a and only because of that fact. IOW, the memory address of d.a is the same as the memory address of d. If that were not the case, then it would not work.
That is poor programming practice because it depends on intimate knowledge of the internal arrangement of the struct. Plus it will be confusing for any programmer reading your code, including yourself (pick up and read a program of yours that you having worked with for several months and you will see what I mean). It is much better practice to set the pointer to the address of the struct thus:
ptr = &d;
To verify that what I said about the addresses of d and of d.a being the same, print out their addresses. The format specifier for a pointer is "%p" and the address is displayed in hexadecimal; eg:
printf("&d = %p\n&d.a = %p\n&d.b = %p\n", &d, &d.a, &d.b);
When you run that and you know the length of the d.a field, you might be surprised by the address of d.b. Because of the processor and data bus architecture, certain address boundaries are more efficient and hence faster to read than others, so to optimize your code for speed the compiler will often add padding between a structure's fields. You will also notice this happening if you add up the lengths of all the fields and then compare that with the value of sizeof(test), which should be greater than the sum of the fields -- in this case, int fields should already be at their optimal word boundaries and so you might not see any padding, in which case you can place a char field between them and the padding will show up. Some programmers try to treat a structure as the padding isn't there and end up having problems; eg, writing the entire structure to disk and then trying to read it in on a different computer that used a different compiler (for example, I wrote an array of structs to disk under Linux at school and then tried working with it under Windows at home; the sizeof of the exact same struct was different on the two systems).
Are structs the same as arrays? No, they are not, mainly because of padding. An array's elements do not have any padding between them. Also, elements of an array are accessed through pointer arithmetic in that the index is multiplied by the sizeof each element and is then added to the starting address of the array. In contrast, the compiler calculates the offset of each of a structure's fields from the starting address of the structure and inserts the appropriate offset into the code that it generates; no pointer arithmetic there except for adding the offset to the struct's address.
BTW, there are such things as arrays of structures and they are used quite commonly.
The structure does not store an address. To repeat, the compiler creates and uses tables of information about the variables and type declarations and uses that information during compile time to generate code that uses that information directly. After all, you have to explicitly name the field you want to access, whereas you can calculate the index you want to use with an array, which happens at run time.
Wait a minute there!
What's x? There's no field named x in that struct declaration! That would not even compile! But if you had used a valid field name there, it works because the compiler knows the offset of that field from the starting address of the struct and inserts that into the object code that it generates.
And if you really want to see how structures work, then read the assembly code that the compiler generates. Read your compiler's documentation for the command switch that will tell it to generate an assembly listing. In all the listings I've seen, the compiler will add the C source code as comments so that you will read a line of C as a comment and below it will be the assembly code that implements that line of C. If you really want to see exactly what your program does internally, that's the way to do it.
Also, some assembly text books describe the assembly code for C's control structures (eg, for statements, switch statements) and for handling different kinds of data. One such book is Assembly Language Programming for the IBM PC Family by William Jones, but I'm sure there are many other books that do the same.
January 30th, 2013, 05:57 PM
Is this all of the question, several variables are undeclared.
"a" and ".x" are undeclared.
The &a and *ptr syntax are a pair of actions on memory and addresses.
The first "&" gets the address of "a" so it can be used as a pointer.
The second "*" says treat the value of the variable that follows as address and use it
Like a ordinary variable.
Ordinary declared variables have a specific amount of memory allocated and the name can e used by common functions and operators as is.
Your arr variable can be used with the array syntax but can also be also accessed with pointer syntax too.
They each have their uses but the examples you have are do not show this well.
Look in you text for more examples or search for c pointer tutorials
January 30th, 2013, 06:42 PM
I should probably mention that my description above was based on my knowledge and experience and that exactly how structures are implemented and structured is entirely up to the compiler. What you find may be different.
For example, my compiler class just dealt with the subject matter on a higher level, since the compiler we were using was the PL/I compiler on an IBM S/370. We used the ALGOL language in the class, but the nearest ALGOL compiler was hundreds of miles away and only accessible via dial-up (this was in 1979). One topic in that class was the implementation of an array. The array started at a particular memory location, but preceding it was a dope vector which contained information on the array's dimensions, size, size of each element, starting location, etc. In other words, the information was there with the array for the program to use at run-time. Though the other approach would be to do away with the dope vector and embed that kind of information in the code. Two different ways of implementing an array, both equally valid. It's possible that a struct could also have a dope vector, though I have seen assembly code generated by MinGW gcc (the compiler that comes with Dev-C++; I think you mentioned that you use that) and I saw the struct's information embedded in the code.
An approach you could take to investigate this would be to run the code in a debugger. Most debuggers allow you to examine a block of memory, so you could examine the struct in memory.
There's also an issue of whether you build the program for debugging or for release. The debugger needs information about the program and its variables and datatypes, so the debug version contains that additional information. Create both a debug and a release version of the same program and compare their sizes; the debug version is much larger. When you release your program to customers, you want to build a release version which does not contain all that inside information about your program. If you ship the debug version, then a software pirate could reverse-engineer your program, which is not something that a company wants to have happen to its intellectual property.
In our situation, the added information in the debug version might confuse the investigation. Just a warning in case.
And I assume that you are familiar with assembly language, at least that you know what it is and how it relates to C and to what the compiler does.
January 30th, 2013, 11:23 PM
Way too much info
Everything said is resonable but I think the response for this question has to be at a more elementary level. Also the OP would have clarify a few things as well to make our answer worth wil to him.
PS. In 79 I was working in PL/I,SPSS and ,God help me , JCL on a IBM 370-168rRunning Roscoe and Wylber front ends to MVS.
January 30th, 2013, 11:58 PM
i find this statement invalid
isnt "a" a structure variable? i think it should be
January 31st, 2013, 12:32 AM
Actually, a is a field in the structure. But, yes, you are correct.
Originally Posted by swapy
Obviously, that is not the code that he says he had run, but rather something he retyped. It would not compile.
January 31st, 2013, 03:45 AM
Originally Posted by Lan07
I am sorry i made some mistakes.It is ptr=&d; and NOT ptr=&a;.ALSO it is (*ptr).d=100; NOT (*ptr).x=100;
I'm really sorry
Comments on this post
January 31st, 2013, 09:11 AM
With this revaluation now you can see that ptr = &d is saving the address of d in ptr.
Are you sure it's (*ptr).d not (*ptr).a. This should reverse the & action to make what in the brackets to be like d. That struc has the element a.
Remember d has no memory associated with it unless it it in .a or .b
January 31st, 2013, 10:31 AM
May I suggest a good practice to follow here?
Originally Posted by Lan07
Only post code that you have compiled and run. This is especially important when you describe what you observed the code to do when you ran it. In your source code editor, highlight the code in question and copy it to the clipboard. Then go to the forum editor here where you're writing your message and paste it between code tags; ie [code] paste your copied code here [/code].
The benefit of this practice is manifold. We won't get distracted from your question with syntax errors that jump out at us -- we're training by years of experience to automatically look for such errors in code. Many times, we will copy and paste your code into our own test programs in order to observe for ourselves what you say you observed, so that code has to compile and actually do what you say.
There will be times where it makes more sense to write a few lines of sample code to illustrate what we're describing or asking, but when you do that you need to be very certain of what you're writing. Recently a very experienced and sharp forum contributor made a simple mistake which was caught. Mildly embarassing, but the point is that we are all prone to making mistakes, so we need to guard against it.
Bottom line: make it a practice to only post working code that you copy-and-paste directly from your working code listing.