Advanced programming concepts
Advanced programming concepts
So I'm using a tutorial online to introduce me into C. But a few days ago I hit a slump and was on hiatus ever since. I can go through just fine until I hit concepts like structures, memory, and linked lists. My brain just freezes up because I cannot get the concept or the syntax correct.
Also, I need to get back up and finish the tutorial so I can move on to building actual stuff.
Also, I need to get back up and finish the tutorial so I can move on to building actual stuff.
Re: Advanced programming concepts
What's your question? If you just want general advice, keep practicing and you'll remember the syntax eventually.
com.sun.java.swing.plaf.nimbus.InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState
Compiler Development Forum
Compiler Development Forum
Re: Advanced programming concepts
It may help to keep in mind that system RAM is just a linear byte array, with each byte numbered from 0 to 4 GB (when running in 32-bit mode).
You can read and write any value to any address in system RAM, but keeping track of what address each value is located at would be a bit difficult, so to make things easier, you can just keep track of the start of a block of "fields", and the offset for each field.
When you add a structure to your code, you are telling the compiler to keep up with each field in that structure. So if you have a structure with 10 fields in it, you can just use a variable that holds the address of the beginning of the structure, and then add the field name to the end, and the compiler will automatically convert that into the correct address for you.
Since structures can contain other structures, you can chain field names together, and "drill down" to a specific field in a tree of structures.
For example:
This tells the compiler to start with the address of the variable named "myStructure", then add the offset for Field1 with that structure, and then add the offset for FieldA within the Field1 structure, and set that address to the value of 4.
If Field1 and FieldA are both the first fields in the structure, then both of their offsets will likely be zero, so the result address would be myStructure + 0 + 0, and the compiler would set the system RAM at that memory address to 4.
Linked lists are a little more complicated, but they are similar to arrays, but instead of putting each value in the array in consecutive memory addresses [0, 1, 2, 3, etc.], each entry in the list can be placed anywhere in system RAM, and each entry has a value, and a memory address to the next value. Then you can just follow along from one value to the next, until you get to the end.
Linked lists are useful in situations where you may need to, say, insert a value in the middle of the list. In an array, you would have to move every value beyond that position up by one "slot", and then put the new value in the correct place. In a linked list, you can just reroute the "next" pointer of the previous value to the new value, and copy the old "next" value to the new value, and you're done.
Hopefully this helps. Let us know if you have any specific questions about how all of this works.
Good luck.
You can read and write any value to any address in system RAM, but keeping track of what address each value is located at would be a bit difficult, so to make things easier, you can just keep track of the start of a block of "fields", and the offset for each field.
When you add a structure to your code, you are telling the compiler to keep up with each field in that structure. So if you have a structure with 10 fields in it, you can just use a variable that holds the address of the beginning of the structure, and then add the field name to the end, and the compiler will automatically convert that into the correct address for you.
Since structures can contain other structures, you can chain field names together, and "drill down" to a specific field in a tree of structures.
For example:
Code: Select all
myStructure.Field1.FieldA = 4;
If Field1 and FieldA are both the first fields in the structure, then both of their offsets will likely be zero, so the result address would be myStructure + 0 + 0, and the compiler would set the system RAM at that memory address to 4.
Linked lists are a little more complicated, but they are similar to arrays, but instead of putting each value in the array in consecutive memory addresses [0, 1, 2, 3, etc.], each entry in the list can be placed anywhere in system RAM, and each entry has a value, and a memory address to the next value. Then you can just follow along from one value to the next, until you get to the end.
Linked lists are useful in situations where you may need to, say, insert a value in the middle of the list. In an array, you would have to move every value beyond that position up by one "slot", and then put the new value in the correct place. In a linked list, you can just reroute the "next" pointer of the previous value to the new value, and copy the old "next" value to the new value, and you're done.
Hopefully this helps. Let us know if you have any specific questions about how all of this works.
Good luck.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Re: Advanced programming concepts
I can understand that concept you explained in the last paragraph. So are you trying to explain memory as "chunks" of fields, right? And you only need to access the first byte or address in a field, am I following you?
For an example, if I'm making a employee database for a workplace, and "name" is an array of 20 bytes, ID is 4 bytes (int, 32-bit) and salary is 4 bytes (float), does that mean we are assigned 28 bytes or addresses in memory?
I guess reading and understanding the syntax is the difficult part for me. What are common techniques for remembering syntax?
For an example, if I'm making a employee database for a workplace, and "name" is an array of 20 bytes, ID is 4 bytes (int, 32-bit) and salary is 4 bytes (float), does that mean we are assigned 28 bytes or addresses in memory?
I guess reading and understanding the syntax is the difficult part for me. What are common techniques for remembering syntax?
- dchapiesky
- Member
- Posts: 204
- Joined: Sun Dec 25, 2016 1:54 am
- Libera.chat IRC: dchapiesky
Re: Advanced programming concepts
In C you have to methods of allocating space for your structure: on the stack or on the heapMark12 wrote:So are you trying to explain memory as "chunks" of fields, right? And you only need to access the first byte or address in a field, am I following you?
For a structure such as:
Code: Select all
typedef struct _employee_structure {
char name[32];
int ID;
float Salary;
} Employee;
Code: Select all
void foo() {
Employee theEmployee;
.....
}
When foo() returns, theEmployee will no longer exist.
Allocating Employee on the heap looks like this:
Code: Select all
void foo() {
Employee *theEmployee;
theEmployee = (Employee *) malloc(sizeof(Employee));
.....
}
When foo() returns, the memory region containing your data will still exist. Presumably foo() did something with the theEmployee pointer so the program knows where the data is.
Perhaps you should check out:
https://www.cs.swarthmore.edu/~newhall/ ... inters.php
Good luck and stay at it!
Plagiarize. Plagiarize. Let not one line escape thine eyes...
Re: Advanced programming concepts
So does every C function have it's own stack then? And how is the size of the stack determined? Is it automatically allocated based on the type of variables on it?
Re: Advanced programming concepts
Yes. And yes.Mark12 wrote:So does every C function have it's own stack then? And how is the size of the stack determined? Is it automatically allocated based on the type of variables on it?
Keep in mind that the CPU doesn't really care about your structures that you define in C. The compiler is responsible for keeping up with all of that, and converting it to addresses that the CPU does understand at build time.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Re: Advanced programming concepts
No. Every C function does not have its own stack. They allocate portions of the one stack for their own use; these are called stack frames. The function will allocate as much space as it needs on the stack. (Actually that's a simplification as different processes will have different stacks, and there are user and kernel stacks. But, for your purposes at this early stage of understanding, tick with the concept of a single stack.)
Re: Advanced programming concepts
There is single stack, but each function cuts off a piece of it for itself using the so-called "prologue"; the function "epilogue" restores the stack to what it was before the function started. This way functions can collectively use a single piece of memory (the stack) without actually stepping on each other's toes (bad things usually happen when they do - as can be seen in numerous "exploits").
Learn to read.
Re: Beginner programming concepts
SpyderTL, why are you trying to explain him what is RAM? And why are you people trying to learn him what is stack when he just started learning C? Now Mark, a good advice for me is to not get confused by stack, heap and such stuff; But to try to learn some easier programming language before trying to learn C. C is very hard programming language for beginners; And it was difficult to me to learn it as my first programming language. Through I did that, it "is not good. Mkay?"
Try some easier programming languages before C, or simply the ones with easy syntax.
Java has similar syntax and easier than C.
--Not related...--
*Applause*
Try some easier programming languages before C, or simply the ones with easy syntax.
Java has similar syntax and easier than C.
--Not related...--
Really? You deserve a nobel prize!No. Every C function does not have its own stack.
*Applause*
Re: Advanced programming concepts
Given your demonstrated inability to understand C I'd advise the OP to take your comments with a large pinch of salt.
Re: Advanced programming concepts
Only a pinch?
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
- Alan Kay
Re: Advanced programming concepts
Hey, I'm midway to learning C anyway. I don't think I should give up now.
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: Advanced programming concepts
I have to agree with Lukand on this one. Most of what has been said here is either wrong or irrelevant. I'll go into the details a bit later.
The first thing you should find out is whether you really want to learn C by getting a sense of where it fits in the larger picture. If the answer turns out to be yes, you want to have a good idea of what it actually is and isn't (I think it's this confusion led to this thread missing the point). I'll try to cover both of these ideas, to the best of my ability. However, the latter will be in the following post because this already grew close to the forum's limit.
People tend to get attached to things and form cults around them. This is as true for programming languages as it is for anything else. What I'm going to say will probably seem controversial but let's stick to arguments rather than emotional attachment, because there isn't any room for that in engineering. As you'll see when I get to the technical bits, C is only simple in spirit. In reality, it's an arcane language that asks for more than it has to offer. There are a few reasons for this:
The other two points have to do with a shift in requirements and the trade-offs we can now afford to make in order to meet them. While back then the bottlenecks were performance and capacity, today it's usually our ability to put together complex systems. There are huge development and maintenance costs associated with large-scale software so we trade some of those extra resources in order to make our systems broader and to improve their security and overall quality. It's simple economics: You get the biggest value by maximizing the difference between profit and cost. What this translates to in practice is that we now have higher-level languages (take this term with a grain of salt; the distinction between low- and high-level is as vague as the distinction between young and old) that have language support for design patterns such as inheritance, exception handling, etc. These things don't allow for new things in any theoretical sense, they're more about organizing code in a sane, disciplined manner. Another example is that Java programs generally run inside a virtual machine called the JVM, for increased protection and portability.
I don't mean to say that these things necessarily make our software slower, of course, because one can make the argument that the higher-level descriptions sometimes make the optimizer's job easier offering a clearer view of the coder's intent, virtual machines can use JIT with runtime profiling for optimizations that would be impossible at compile time, etc. However, in practice, they often do.
Does all this mean that C has no more place in the industry. I'd say it still serves a couple of purposes. The first is, obviously, that some code bases are just too expensive to translate. The other is embedded platforms, where it is often the least horrible option. Furthermore, C compilers are dirt easy to write so if the budget for the platform you are developing is limited, you can get software up and running on them in no time, be it existing software or future software. This is exactly why C is available pretty much everywhere.
The first thing you should find out is whether you really want to learn C by getting a sense of where it fits in the larger picture. If the answer turns out to be yes, you want to have a good idea of what it actually is and isn't (I think it's this confusion led to this thread missing the point). I'll try to cover both of these ideas, to the best of my ability. However, the latter will be in the following post because this already grew close to the forum's limit.
People tend to get attached to things and form cults around them. This is as true for programming languages as it is for anything else. What I'm going to say will probably seem controversial but let's stick to arguments rather than emotional attachment, because there isn't any room for that in engineering. As you'll see when I get to the technical bits, C is only simple in spirit. In reality, it's an arcane language that asks for more than it has to offer. There are a few reasons for this:
- Even though exceptions exist, for the most part, C has to remain backwards compatible.
- Computers are much faster today than they were when C was designed. The PDP-7, on which C originates, is orders of magnitude slower than today's average smartphone.
- The scale of software has grown by a lot. A game engine for today's AAA titles is much more complex than the software that got Apollo 11 to the Moon.
The other two points have to do with a shift in requirements and the trade-offs we can now afford to make in order to meet them. While back then the bottlenecks were performance and capacity, today it's usually our ability to put together complex systems. There are huge development and maintenance costs associated with large-scale software so we trade some of those extra resources in order to make our systems broader and to improve their security and overall quality. It's simple economics: You get the biggest value by maximizing the difference between profit and cost. What this translates to in practice is that we now have higher-level languages (take this term with a grain of salt; the distinction between low- and high-level is as vague as the distinction between young and old) that have language support for design patterns such as inheritance, exception handling, etc. These things don't allow for new things in any theoretical sense, they're more about organizing code in a sane, disciplined manner. Another example is that Java programs generally run inside a virtual machine called the JVM, for increased protection and portability.
I don't mean to say that these things necessarily make our software slower, of course, because one can make the argument that the higher-level descriptions sometimes make the optimizer's job easier offering a clearer view of the coder's intent, virtual machines can use JIT with runtime profiling for optimizations that would be impossible at compile time, etc. However, in practice, they often do.
Does all this mean that C has no more place in the industry. I'd say it still serves a couple of purposes. The first is, obviously, that some code bases are just too expensive to translate. The other is embedded platforms, where it is often the least horrible option. Furthermore, C compilers are dirt easy to write so if the budget for the platform you are developing is limited, you can get software up and running on them in no time, be it existing software or future software. This is exactly why C is available pretty much everywhere.
Last edited by Love4Boobies on Sat Dec 31, 2016 3:23 pm, edited 1 time in total.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: Advanced programming concepts
All that said, you want to learn C. It's important to realize that C (and most other programming languages, for that matter) is separate from its implementations. In particular, it's an abstract machine and that is what you write code for rather than for a computer. The distinction is important because although you likely use a compiler (i.e., something that translates programs from one language to another; e.g., C to assembly or machine code or even C to Java), all that C implementations are required to do is to respect the semantics of the language.
Assumptions like "a byte is 8 bits wide," "int is a 32-bit type," "dynamic allocation happens on a heap," or "memory is linear" might make sense for a particular C implementation but will lead to portability problems in the general case. In truth, C bytes are CHAR_BIT bits wide, int has a length of sizeof (int) bytes and its representation can vary widely (it is aligned on an alignof (int)-byte boundary, its range is given by INT_MIN and INT_MAX, it can have padding bits, trap representations, its signedness is represented in one of three ways) and semantics in even more ways that I won't get into here, the data structures used for dynamically allocated storage are up to the implementation, and memory in C is really segmented rather than flat.
The convention by which C compilers map C programs to a particular platform (the target ISA, the calling convention, type representations, the executable file format, etc.) is called an ABI. However, C implementations are not limited to compilers: they can also be interpreters (you may have heard of the terms compiled language and scripting language; these are really misnomers as they refer to a quality of implementations, not of the language proper). In the case of interpreters, even more of the usual assumptions are likely to break down.
The reason I'm throwing out all these details is not to scare you but to get the point across that C is its own (arcane) beast and that you should be aware of that if you are writing C rather than code for a particular C implementation. Someday, you may want to switch to a different implementation or even to a different platform. It's better to be forward-thinking than to have to go through the expensive process of developing almost from scratch.
Also, you noted that you're learning C from some online tutorials. I highly recommend you not do that for anything related to engineering. Tutorials are very limited in their scope, most often written by inexperienced people, and the worst part is that you end up thinking you've learned more than you have or may have even learned the wrong thing. You won't believe how much of the information out there is tainted. For instance, there's a very popular book called C: The Complete Reference by Herbert Schildt, who even sat on the standards committee. It's a technical nightmare; he does not understand C at all and although it has led to some very negative reviews by other people on the committee and elsewhere, people still read it to this very day.
Although I haven't updated this page in a very long time, I've put down some books that I would wholeheartedly recommend to you on this page. There are also a couple of books by P.J. Plauger that I meant to put on there but never got around to it.
Assumptions like "a byte is 8 bits wide," "int is a 32-bit type," "dynamic allocation happens on a heap," or "memory is linear" might make sense for a particular C implementation but will lead to portability problems in the general case. In truth, C bytes are CHAR_BIT bits wide, int has a length of sizeof (int) bytes and its representation can vary widely (it is aligned on an alignof (int)-byte boundary, its range is given by INT_MIN and INT_MAX, it can have padding bits, trap representations, its signedness is represented in one of three ways) and semantics in even more ways that I won't get into here, the data structures used for dynamically allocated storage are up to the implementation, and memory in C is really segmented rather than flat.
The convention by which C compilers map C programs to a particular platform (the target ISA, the calling convention, type representations, the executable file format, etc.) is called an ABI. However, C implementations are not limited to compilers: they can also be interpreters (you may have heard of the terms compiled language and scripting language; these are really misnomers as they refer to a quality of implementations, not of the language proper). In the case of interpreters, even more of the usual assumptions are likely to break down.
The reason I'm throwing out all these details is not to scare you but to get the point across that C is its own (arcane) beast and that you should be aware of that if you are writing C rather than code for a particular C implementation. Someday, you may want to switch to a different implementation or even to a different platform. It's better to be forward-thinking than to have to go through the expensive process of developing almost from scratch.
Also, you noted that you're learning C from some online tutorials. I highly recommend you not do that for anything related to engineering. Tutorials are very limited in their scope, most often written by inexperienced people, and the worst part is that you end up thinking you've learned more than you have or may have even learned the wrong thing. You won't believe how much of the information out there is tainted. For instance, there's a very popular book called C: The Complete Reference by Herbert Schildt, who even sat on the standards committee. It's a technical nightmare; he does not understand C at all and although it has led to some very negative reviews by other people on the committee and elsewhere, people still read it to this very day.
Although I haven't updated this page in a very long time, I've put down some books that I would wholeheartedly recommend to you on this page. There are also a couple of books by P.J. Plauger that I meant to put on there but never got around to it.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]