Learning C
Published at Apr 13, 2024
Compiler
We need a compiler that translates your source code into an executable program that your machine can understand. In most Linux distributions, the GCC command comes pre-installed. However, if it’s not, you can install it in Debian based distributions like Ubuntu, by running the command
sudo apt-get install gcc
There are other compilers like Clang,TinyCC,etc . I will stick with gcc as start point.
Debugger
I will also learn about GBD, more about this in another post.
Checking memory leaks?
I perceive some bad press on C due to high responsability on the software engineer to take care of memory management, leading to memory leaks problems. I found Valgrind, a tool that can help you find memory leaks , I will test it further in coming posts.
Testing
Found criterion. I used it in the usb project, and really liked it. Github Criterion Intro video
Some C syntax
I followed these guides:
- GNU.org
- [tutorialspoint.com](https: // www.tutorialspoint.com/cprogramming/c_overview.htm)
/*
*****************************
* ***** HEADER FILES
*****************************
*Include necessary header files that contain declarations of functions,
*constants, and macros that can be used in one or more source code files. Some
*popular header files are as
*/
#include <stdio.h> //Provides input and output functions like printf and scanf
#include <stdlib.h> //Contains functions involving memory allocation, rand function, and other utility functions.
#include <math.h> //Includes mathematical functions like sqrt, sin, cos, etc.
#include <string.h> //Includes functions for manipulating strings, such as strcpy, strlen, etc.
#include <time.h> //Contains functions for working with date and time.
#include <stdbool.h> //Defines the boolean data type and values true and false.
#include <limits.h> //Defines various implementation-specific limits on integer types.
#include <ctype.h> //Contains functions for working with date and time.
/*****************************
* ***** CONSTANTS
*****************************/
// Constant with define (Note: 1. NO ; in endline 2. No type declaration)
#define PI_DEFINE 3.14159
// Constant with const
const float PI_CONST = 3.14159;
// What is difference defining constant both ways?
// !with #define, compiler will replace PI_DEFINE everywhere in your code with
// value 5
// !with const, wherever you use Pi_CONST it will point back to this constant
// value
/*****************************
* ***** MACRDS
*****************************/
// normally I would just use r*r but just to use math library
#define AREA(r) (PI_DEFINE * pow(r, 2.0))
/*****************************
* ***** GLOBAL DECLARATION
*****************************/
int globalB = 10; // Global declaration
int main() {
printf("Hello world!\n"); // stdio library
// Using constants
float useAdef = PI_DEFINE + 1; // here PI will be replaced (LITERALLY)
float useAconst = PI_CONST + 1;
printf("Using constants: %f and %f\n", useAdef, useAconst);
// Using macros
float area = AREA(5);
printf("Area %f\n", area);
/*****************************
* ***** DATA TYPES
* Type of variable determines how much space it occupies in storage
*****************************/
// 1. Basic types
// Integer and flating types ONLY
char char1 = 100; // 1 byte | -128 to 127 or 0 to 255
unsigned char uchar1 = 250; // 1 byte | 0 to 255
signed char schar1 = -125; // 1 byte | -128 to 127
int int1 =
10000; // 2 or 4 bytes | -32768 to 32767 or -2147483648 to 2147483647
unsigned int uint1 = 20000; // 2 or 4 bytes | 0 to 65535 or 0 to 4294967295
short short1 = 1010; // 2 bytes | -32768 to 32767
unsigned short ushort1 = 65000; // 2 bytes | 0 to 65,535
long long1 = 38282828; // 8 bytes
unsigned long ulong1 = 38282828; // 8 bytes
// printf %lu is long unsigned
printf("%lu\n", sizeof(ulong1)); // sizeof gets size of variable
float float1 = 1.3; // 4 bytes | 1.2E-38 to 3.4E+38 | 6 decimals
double double1 = 3.3E33; // 8 bytes | 2.3E-308 to 1.7E+308 | 15 decimals
long double ldouble1 =
1.1E+300; // 10 byte | 3.4E-4932 to 1.1E+4932 | 19 decimals
// 2. Enumerated types
enum Level { LOW, MEDIUM, HIGH };
enum Level l1 = MEDIUM;
printf("Level enum : %d\n", l1);
enum Level100 { LOW100 = 25, MEDIUM100 = 50, HIGH100 = 75 };
enum Level100 l2 = MEDIUM100;
printf("Level enum : %d\n", l2);
// 3. Void data type
//
// 4. Derived types
// Pointer, array , structure, union and function
int x = 10;
int *pX = &x;
// TODO : talk about memory size, how pointer can hint your memory ram ?
printf("Address of var x: %p\n", &x);
printf("Address stored in pX variable: %p\n", pX);
printf("Value of *pX variable: %d\n", *pX);
// Declared array but uninitialized elements .It may show certain
// random garbage values.
int marks[5];
for (int i = 0; i < 5; i++) {
printf("%d ", marks[i]);
}
printf("\n");
int marks2[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) {
printf("%d ", marks2[i]);
}
printf("\n");
int marks0[5] = {0}; // initializing to zero
for (int i = 0; i < 5; i++) {
printf("%d ", marks0[i]);
}
printf("\n");
// size of array is the size of bytes!
// an int has 2 or 4 bytes size(default to 4)
printf("Size of array: %ld\n", sizeof(marks0));
for (int i = 0; i < 5; i++) {
printf("a[%d]: %d \t Address: %p\n", i, marks0[i], &marks0[i]);
}
/* The C language does not check whether array indices are in bounds, so if
* the code uses an out-of-range index, it will access memory outside the
* array. To be fair, this also happens with other languages as well .
* */
struct Student {
char name[20];
int marks, age;
};
struct Student me;
union ab {
int a;
float b;
};
return 0;
}
Some useful links
https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/ https://ioflood.com/blog/install-gcc-command-linux/ https://valgrind.org/docs/manual/quick-start.html https://cs.brown.edu/courses/csci0300/2024/assign/labs/lab1.html