[ON-GOING] C Review

2024-07-18

Variables and Operators

The main data types in C: int, float, double, and char.

printf

symbol type
%d or %i int
%f double or float
%c char

float is 4 bytes double is 8 bytes

Constants

Never change.

const int DAYSINWEEK = 7;

Casting Types

There are two types of conversions, implicit and explicit. When you set one variable to be the same as another, such as a = b above, but their types do not match, the compiler will try to convert them. However, this can be dangerous as you might not know what values will be in the variable at runtime, and it might not be implicitly convertible to another type. Our example above was implicit, the compiler in this case will make a best guess.

double testScore;
int displayScore;
displayScore = (int)testScore;

Operators

Nothing noteworthy.

Pointers

Pointer Arithmetic

The only arithmetic operations allowed for pointers are addition and subtraction. Conceptually, adding to (or subtracting from) a pointer means the pointer will point to some new address. Multiplication is not allowed because the address of a byte of memory is usually a large number; therefore, multiplying an address may yield an even larger number, possibly representing an address outside the bounds of the available memory space. Division is not allowed as it potentially allows a pointer to illogically point to an address with a non-integer index.

The important thing to note here is that adding n to a pointer does not increment the address to point to a value n bytes away. It moves the pointer by n * (size of the data type in bytes). For example, if a pointer to an int, the size of which is four bytes, initially contains address 100 (we will use a decimal address for simplicity), and three is added to the pointer, the pointer will now point to address 112.

#include <stdio.h>

int main() {
  double* ptr1;
  ptr1 += 5;
  ptr1 -= 4;
}

Pointers & Arrays

Struggle bus for this one…. Not great. Dereferences were kind of weird, and single quotes got me stuck for a while for some reason.

#include <stdio.h>
#include <string.h>

int main() {
  int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  char s[] = "Farmer Jack realized that big yellow quilts were expensive!!";

  int *ptr = &arr[9];
  for (int i = 9; i >= 0; i--){
      printf("%i",arr[i]);
  }

  char *ptr2 = &s[0];

  for (int i = 0; i < strlen(s); i++) {
    *ptr2 = '#';
    ptr2++;
  }
}

Memory Management

Function Use Case
malloc() Use this function to reserve as many bytes as you want on the heap
calloc() Use this function to reserve memory for some number of ints, doubles, or any other data type.
realloc() Use this function to expand or contract a block of reserved memory (reserved by either malloc() or calloc()).
free() Use this function to release previously allocated memory.

Small Projects

String Copier aka poor-man strcpy()

#include<stdio.h>
#include<string.h>
 
void copy(char* dst, char* src){
  int ptr = 0;
  while(*src != '\0'){
    dst[ptr] = *src;
    ptr++;
    src++;
    printf("%s", src);
  }

  printf("%s", dst);
}

 
int main(){
 char srcString[] = "We promptly judged antique ivory buckles for the next prize!";
 char dst[strlen(srcString+1)];
 copy(dst, srcString);
}

Echo Server

[ … ]

LeetCode Practice

Palindrome Number

Given an integer x, return true if x is a palindrome (An integer is a palindrome when it reads the same forward and backward.), and false otherwise.

Nothing too special here, just iterate over the x value using % 10. Placed the numbers into a char str array in reverse order, then use atoi() to change the type from char str to int. Finally, just compared and return. I didn’t find this overly complicated but my code definitely lacks in simplicity.

bool isPalindrome(int x) {
    if (x < 0) {
        return false;
    }
    
    char str[12];
    int i = 0;
    int num = x;

    while (num > 0) {
        str[i++] = num % 10 + '0';
      	num /= 10;
    }

    int reverse = atoi(str);
    
    if (reverse != x) {
        return false;
    }
    
    return true;
}

Merge Two Sorted Lists

You are given the heads of two sorted linked lists list1 and list2. Merge the two lists into one sorted list. The list should be made by splicing together the nodes of the first two lists. Return the head of the merged linked list.

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    struct ListNode dummy;
    dummy.next = NULL;
    struct ListNode* curr = &dummy;

    while (list1 != NULL && list2 != NULL) {
            if (list1->val > list2->val) {
                curr->next = list2; 
                list2 = list2->next;
            } else {
                curr->next = list1; 
                list1 = list1->next;
            }
        curr = curr->next;
    }
    curr->next = (list1 != NULL) ? list1 : list2;
    return dummy.next;
}