This is the first part in a possibly multi-part series of posts about the C programming language. Itâs based not on common examples or what youâll see your particular C compiler output, but on whatâs written in the actual standard(s) that define the language. That being ISO/IEC 9899, in particular the 2018 revision (often named C17 or C18), however due to upcoming significant changes in the next revision (C2X), Iâll be skipping over a couple bits here and there that will be deprecated or removed by said revision, Iâll also revert to older versions if needed for special cases. All that being said, unless stated otherwise these posts are about C17. This series also assumes a baseline level familiarity with programming in general and expects you to know the general syntax style of C (if youâve written or read and C++, Java, C#, or any similar language youâre good).
Due to the nature of C17 being an ISO/IEC document, it is not freely available for download, however the final working draft version of it is freely available, and there should be no significant changes between it and final. Link here.
Now, in what might seem like a very odd choice, weâre going to instantly skip to section 6 of the standard, not only that weâre skipping directly to 6.2.5 (page 31), because this is what defines the fundamental types of the language. Paragraphs 2, 4 and 6 are the important ones right now. From 2 we learn that the type _Bool (just bool in C2X) is at least large enough to hold the values 0 or 1 (hence its name, bool, short for boolean). Then we come to paragraph 4, which states there are 5 standard signed integer types: char, short, int, long, and long long (thereâs also a statement about extended types but that can be ignored for the moment). Finally we hit paragraph 6, which simply states that all signed integer types have an unsigned equivalent that can be written by simply attaching the word unsigned to one of the types (ex. unsigned int), and that these 5 unsigned types combined with _Bool make up the set of unsigned types, and that any unsigned type takes up the same amount of storage/memory space as its corresponding signed type.
Moving back slightly to paragraph 5 we learn that signed char and char take the same amount of memory (and as such so does unsigned char), it also states that the int type should be the natural operating size of whatever machine architecture the code is being written for (so long as it satisfies a minimum value requirement). Moving forward to paragraph 9 we learn that, as you would expect, the signed types can store negative and positive values, and that the unsigned types can only store positive (or zero) values. We also learn that by definition unsigned values can not overflow, instead their value simply wraps around the range, however this is often referred to as overflow regardless.
Yet further down (paragraph 15, next page) we learn that char, signed char, and unsigned char are all different types, however char must match either char or unsigned char (the reasoning for this is that a compiler is free to choose the most efficient match for processing).
So with all that jumble out of the way what did we actually learn? Well: there exist 5 fundamental integer types: char, short, int, long, and long long, and that signed and unsigned versions of each exist, we also know thereâs an unsigned type, _Bool that can represent the values 0 and 1. Together these make up the integer types of C.
Beyond integers thereâs also floating point types, float, double, and long double, but those are a much more complicated subject that are outside the scope of this post. Thereâs also the void type, which has confusing wording that basically boils down to âyou canât use this, it represents nothingâ (which is why functions with no return value have their return type marked void). And finally that you can make arrays out of these types (except void), make structure types that contain any number of these types (except void), make union types (complicated subject, think a box that can store only one type (except void) at a time), you can declare functions that return any type, you can have a pointer to any type (including void in order to represent a pointer to an unknown type), and finally that any type can be made atomic (safe for access from multiple threads).
Most of that statement can be freely ignored for now, itâs a mess that weâll (hopefully) get into later. The important bit to know is that you can build other types out of the fundamental types.
Moving beyond that section and into 6.2.6 we learn from 6.2.6.1 Paragraphs 2-4 that objects (any typeâs representation in memory basically) is made out of a continuous sequence of bytes. Moving to 6.2.6.2 we get to the representation of integer types, which is pretty much what you would expect for unsigned values (an unsigned integer of size n value bits can store 2n values from 0 to 2n-1), signed integer types in C17 list three different representations, however C2X is reducing that down to just twosâ complement (a signed integer of size n bits can store from -2n-1 to 2n-1-1, negative zeros are not possible).
So far: there exist integer types, and these store values in the expected way, but what are the range of values they must store?
Section 5.2.4.2.1 (page 20), paragraph 1 states that all implementations of the language must have the integer types be able to represent at least the values in the ranges listed below, meaning an implementation is free to expand the range if it sees fit (like how many do with int). From here we learn that a char must be at least 8 bits, and as such a signed char must be able to represent -127 (-128 in twosâ complement) to 127, and that an unsigned char is 0 to 255. Helpfully the actual (minimum) number of bits for each type is specified in a comment next to the definition. short is 16 bits/2 bytes, int is also 16 bits/2 bytes (again often expanded to 32 bits/4 bytes), long is 32 bits/4 bytes, and long long is 64 bits/8 bytes. _Bool due to its nature as a boolean type is not mentioned (actually any values placed into an object of type _Bool will become 0 if the value is 0 or 1 otherwise).
In summary: 6 types, _Bool (0 or 1), char (at least 8 bits), short (at least 16 bits), int (at least 16 bits, often 32), long (at least 32 bits), and long long (at least 64 bits).
So thatâs it? For now yeah, those are the basic integer types of the C programming language, I know it was messy and weirdly formatted and confusing at times but I hope it helps understand the language a bit more, or at the very least was entertaining (even if that entertainment derived from âwhat the hell is this language?â). However, these complexities are part of the reason I love this language so much, everything is well defined but still variable depending on the system and compiler, thereâs a reason for everything in this language ranging anywhere from âoldâ to âfor performance reasons we canât mandate thisâ, which if this series continues weâll really get into. But for now, I hope this was enough of a taste of the standard to either make you interested in seeing more, or scare you the hell away forever. Thank you for reading and have a good time. If you have any suggestions for future parts or ways I could improve these writings please inform me. I need to go to sleep now.
Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
â Live Streamingâ Interactive Chatâ Private Showsâ HD Quality
Anya is LIVE right now
FREE
Free to watch âą No registration required âą HD streaming
This is part 2 in a series of posts about the C programing language, part 1 (and series details) can be found here
Well everyone, I hope you kept your copy of the free version of the standard from last time, 'cause that thing isn't going away any time soon. To give a quick rundown on what this part is going to cover, it's going to cover the rank of integer types, and it's going to go over the definition of a byte in the language and some of its consequences.
Rank
The âinteger conversion rankâ (6.3.1.1 p1, page 37) is a scale (or ranking) of all the integer types from _Bool to unsigned long long (and possibly implementation defined types). The definition effectively states that all integers have some rank, that the signed and unsigned version of a type have the same rank (and charâs rank equals that of its signed and unsigned versions), that a type with a greater precision (number of bits) will always have a greater rank than a lower one, and that even if two types have the same representation (ie. same width) one will always have a greater rank. It also gives us an outline of the rank of the fundamental (called the âstandard integer typesâ in the document) integer types: _Bool, char, short, int, long, and long long, and it also handily gives us the info that any implementation defined types (such as say __int64) has a rank less than a corresponding standard type with the same rank (such as (possibly) long long). It also states that any implementation defined types with the same precision have some ranking between each other, this is important because it establishes a total order (any integer typeâs rank is either less than or greater than any other type).
So whatâs the deal with ranks? Well notice the full title contains âconversionâ, ranks are very important for determining integer type promotion. Any type whoâs precision (and as such rank) is less than an int will be transformed into an int (if its value would fit, unsigned int otherwise) when performing an arithmetic operation (add, sub, mul, div), a shift operation, a âsignâ operation (negation (- operator) or the + operator), or when passed âcertain argument expressionsâ (usually var arg functions). Note this is simply a promotion in width only, the values contained within remain completely unchanged. What this means is that adding a char to a char will in fact actually become the addition of an int and an int.
Ranks are also very important for another conversion, arithmetic operations on differing types (6.3.1.8 p1, page 39). Firstly if one of the types in the expression is a floating point type long double, double, or float) then the other type is promoted to that floating point type (you donât want to lose the fractional part just cause you added an int after all), but after that is where rank becomes important. If the types are the same nothing happens and the expression goes on as usual, but if the types differ then the type with the lower rank is promoted to the type with the higher rank (usually, thereâs a caveat about precision that basically boils down to âif promoting it would cause signed data loss, then promote both types to an unsigned versionâ). Whatâs all this mean? Well it basically means that given any two types (say int and unsigned long long) any operation between them will cause the lower rank type to become the higher rank type (here the int becomes an unsigned long long).
These results are all bound to the definition of conversion (6.3.1.3, page 38). Long story short on that if you convert a signed type to an unsigned type then the value stored will have 2n (where n is the value bit width of the new type) added to it over and over until the result falls within range of the new type, however if you convert an unsigned type to a signed type and the value can not fit within the signed type its up to the implementation what happens (since its implementation defined it must be documented somewhere). Conversion also comes into play in a few other places, like assigning values of one type to another (ex. char to int) or passing arguments to functions (ex. passing an int value to a function expecting long).
Byte(s)
Ok this one is going to be a lot simpler (and more fundamental) than ranks, Iâve only put it after type introduction and ranks because it's easier to understand that way (at least for me, sorry if you find it otherwise).
Alright letâs get the big things out of the way first, a byte is simply defined as âaddressable unit of data storage large enough to hold any member of the basic character set of the execution environmentâ (3.6, page 4), which just means it can hold all of the basic ASCII (printable) characters excluding â`â (the backtick), â$â and â@â as well as some control characters like new lines and such. The other big thing is that a byte is at least 8 bits (5.2.4.2.1 p1, page 20), but can be more (there have been systems with 9 bit bytes before), and also that a char (and signed and unsigned versions) are exactly one byte, no more, no less.
The other thing is that any (non-bitfield) object (an object in C is defined in section 3 and is simply the value contained within some memory location) is composed of n continuous bytes (6.2.6.1 p4, page 34), meaning that the total width of the object in bytes is n multiplied by the number of bits in a byte. It also goes on to detail that any objects with the same bit pattern (except for floating point NaN values) will compare as equal, however not all objects that compare equal need to have the same bit pattern (ex. negative 0 and ânormalâ 0).
Further down (6.2.6.2) we learn that any integer type (except unsigned char which is only value bits) can be divided into value bits (bits that contribute to the actual value of the number) and padding bits (bits that are just there to make the integer fill the full width of a n bytes), and that there need not be any padding bits. As expected an unsigned type can store any value between 0 and 2v-1, where v is the number of value bits, and a signed type can store between (at least) -2v-1 and 2v-1-1 (due to needing a sign bit).
All other objects have n bytes contained within them, however their usage of the bits will differ greatly depending on their use, for example floating point types need to divide their bits between sign, exponent, and mantissa, and structs use their bytes to hold other types and objects.
Conclusion
So thatâs it, thatâs ranks and bytes in the C programming language. Ranks determine how integer types combine together, and bytes make up every object in the language and determine their value.
Thank you for reading, once again I stayed up late to write this, except it's even worse since I have something critical tomorrow. If you have any comments, concerns, or ways to improve this series drop them in the replies.
Start your journey in Coding with the Best C Programming Course
Would you like to begin on your programming journey? The Best C Programming Course language is a great first step in that direction, and Takeoff upskill will take you along with a very beginner-friendly course full of practical concepts. One of the oldest and strongest programming languages, C finds extreme utility in system programming, embedded systems, experimenting with making games, and making modern operating systems in Windows and Linux. Learning C means to know basically how software works on a very micro level, thus laying a foundation for learning must-haves like C++, Java, or Python.
Takeoff upskill offers a C Programming course with the student, beginner, and working professional in mind to brush up their programming skills. Our course is for anyone: whether you are from a technical background or are merely curious about coding-the course covers everything in a simple and straightforward manner.
What You Will Learn:
Basics of C language (syntax, variables, data types)
Control statements (if-else, loops)
Functions and arrays
Pointers and memory management
Structures and file handling
Hands-on coding practice and mini projects
At YoungMinds, the expert trainers were doing practical teaching by way of live examples and exercises. Hence, you may be writing and debugging codes on your own, which shall boost confidence along with problem-solving skills.
Apart from being equipped with assessments, quizzes, and projects from time to time to keep track of your progress, you will reach a level by the end of the course to writing your own programs and reading computer working behind the scenes. Whether you're interested in job interviews, career building in IT, or just programming for fun, this might be the best course to start with.
Conclusion
Studying Best C Programming Course is a knowledgeable ever choice for somebody who wants to cement down underrated concepts of coding. With help from professional tutors and straightforward teaching methods at Takeoff upskill, this very course is an easy way for any beginner to learn and find his/her way into programming. Whether for further studies, job, or personal growth, this is your perfect start. Enroll and create a strong foundation of coding with C!
Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
â Live Streamingâ Interactive Chatâ Private Showsâ HD Quality
Anya is LIVE right now
FREE
Free to watch âą No registration required âą HD streaming
tart your journey into the world of Computer Science with a beginner-to-advanced course covering core concepts like Programming (C, C++, Python), Data Structures, Algorithms, Operating Systems, Database Management, Computer Networks, and emerging fields like Artificial Intelligence and Machine Learning.
This course is ideal for students aiming to build a solid foundation in software development, data analytics, or IT careers. With hands-on learning and expert guidance, it prepares you for real-world challenges in tech.
Students from Uttam Nagar and Yamuna Vihar looking to gain practical skills in computer science can benefit greatly from this industry-relevant training program. Join now to turn your tech passion into a profession!
C Programming Language Tutorial: A Beginnerâs Infographic Guide
This beginner-friendly infographic offers a clear and concise overview of the C programming language. Learn the basics of syntax, data types, loops, and functionsâall visually explained for easy understanding. Ideal for students and aspiring developers, this guide simplifies C programming concepts to help you get started quickly and confidently. Perfect for quick reference and foundational learning in coding.
The Ultimate C Programming Language Tutorial for Beginners and Experts
This Ultimate C Programming Language Tutorial for Beginners and Experts is designed to help you master C programming from the ground up. Covering key topics like variables, loops, functions, pointers, and memory management, this tutorial provides real-world examples and hands-on coding using an Online C Compiler. Whether you're a beginner or an experienced programmer, enhance your skills and build efficient, high-performance applications with the C programming language today!