How to C

By Jenny Wang on May 27, 2019
~10 min. read

============================

#include <stdio.h>

  • standard input and output

#include <string.h>

  • strings

#include <stdlib.h>

  • exit() to exit out of code
  • rand() to create random numbers

#include <stdbool.h>

  • booleans
  • can use bool instead of _Bool

#include <ctype.h>

  • getchar() recieves a string/char, can be put in variable
  • putchar(string) display the char
  • isalnum(char) and others (see below)
  • has an alphanumber been passed in? (a for 10, b for 11, etc)

#include <errno.h>

  • error handling

#include <math.h>

  • calculate power of something

Define:

==========

#define MYNAME "Derek Banas"

  • all uppercase, a constant

#undef MYNAME

  • can redefine afterwards

Concepts and Strategies:

==========================

  • main looks like int main(){} and returns a 0 at the end

  • & is to get the pointer, * is for the value
    • inverses
  • Print things on the screen from an array:
    char *randomString = "Just some random stuff";
    while (*randomString){ //null=>0=>ends while    
      putchar(*randomString++); //increment to chars
    }
    //OR
    int i = 0;
    while(randomString[i] != '\0'){
      putchar(randomString[i++]);
    }
    
  • if you initialize a, but don’t give it a value before incrementing it, computer will take whatever was inside the place a is, increment it, and spit it out. “Random garbage”

  • arrays use row-major ordering, so it is array[y][x]

Data Types:

=============

char firstLetter = 'L';
int age = 38; //up to 32000
long int superBigNum = -3229384234; //bigger
float piValue = 3.14; //decimals (38 decimal #s)
double reallyBigPi = 3.1423842323i4uy23i4;

To describe variables:

=========================

unsigned = no negative digits

const = constant, unchanging

size_t = stores the amount of data in bytes

extern = variable was defined elsewhere, but use that var here, too

static = basically a “global” variable with a scope limited to where it was defined - functions: “you can’t call me out of my scope! >:D”

Relational:

=============

TRUE is anything other than 0

  • can an int be used in if(int) ?

FALSE is also 0

>, <, >=, <=, ==, !=, &&, ||

  • result comes out as 1 (true) and 0 (false)

  • !0 equals 1

  • !1 equals 0

  • To choose between two options:

      char* legalAge = (custAge > 21) ? "true" : "false";
    
    • if true, return true. If false, return false
    • can be put inside the %s part of printf()

Casting a value:

==================

  • to temporarily change the type

      //when the two numbers are ints:
      printf("numberEx / numberEx2 : %f", (float)numberEx/numberEx2);
    

Strings:

===========

  • If made by char ex[] = {‘C’, ‘a’, ‘\0’}, include ‘\0’ “naw” to end the string
  • or do char myName[] = “Something” (automagically puts \0)
  • see Functions

Pointers:

============

  • To pass data to other functions so they can use that local variable as well

  • can be in %p and %d (hexidecimal or not)

  • * to get what’s in the pointer
  • & to make it into a pointer

  • print the first index in an array:
    printf("First: %d", *array);
    
  • print any other index because they are next to each other:
    printf("Thrid: %d", *(array + 2));
    

Structs:

===========

  • more than one data type to describe something
  • need * for strings because of pointers

  • Example:
      struct dogs{
    
          const char *name;
          int height; 
    
      };
    
  • use typedef struct to make it so you don’t have to put struct everywhere else
    • “Make a new variable type”

    • Example:

            typedef struct dog{
      
                const char *name;
                int height; 
      
            } dog; //you can call it with dog
                    //can put multiple names
      
  • To put info in:

      struct dog spike = {"Spike", 90};
    
  • To get the info in the struct:
      theName = theDog.name; //use the . OR
      theName = theDog->name; //OR
      theDog->name = theName;
    
  • To get addresses, use theDog.name for strings and
      &theDog.avgHeight for ints
    
  • When struct is passed to function, new struct is created, so need pointers
  • When doing * with structs, use ():
      (*theDog).weight = newWeight;
    
    • OR you can do
        *theDog->weight = newWeight;
      

struct dog cujo2 = cujo;

  • Can copy everything in a struct, including pointers

Union:

========

  • store 1 pieces of data that can be any type, but is not more than one type at a single time

  • Making one:
      typedef union{
            
          short individual;
          float pound;
          float ounce;
    
      } amount; //this union is named amount
    
      //set amount as 16, other values follow
      amount orangeAmt = {.ounce = 16};
    
      //changes the value of the whole union
      orangeAmt.individual = 4;
    
  • BE SURE TO USE THE CORRECT DATA TYPE

  • Can put them in structs
  • To initialize:
    • Ex: orangeProduct is a type of struct named orangeProduct, theAmount is an union, so
        orangeProduct productOrdered = {"Chiquita",
            .theAmount.ounce = 16};
      

Linked List:

==============

  • Essentially make an infinitely long list with structs

  • Format of each struct:

      typedef struct product{
    
          const char *name;
          float price;
    
          struct product *next; //pointer to next struct
    
      } product;
    
  • if pProduct is the pointer of the given product, the next one in the line is pProduct->next

  • Add a new struct to the end:
      tomato.next = &potato;
    
  • add a new product, apple, between potato and lemon:

      potato.next = &apple, apple.next = &lemon, lemon.next = NULL
    
  • To go through all structs:
    • go through all the items through next until you get NULL
  • To search for a struct:
    • recieve a *productName
    • set a varialbe to the first variable in the struct => name
    • use strcmp() to compare
  • Deleting an item:
    • Ex: Tomato, Potato, Lemon
    • see what’s before potato from the time you were scanning for potato
      • potato’s next is now tomato’s next
    • free() potato

Macros:

==========

  • A fragment of code that is given a name
  • name is read => whole code is pasted in
  • conventional = names are all UPPERCASE
  • Ex: #define MACRO_THINGIE 10 -> 10 is put in MACRO_THINGIE, replaces it

  • can make multiple lines
      #define MACRO_NUMBERS 10 \
                              2 \
                              3
      int x[] = {MACRO_NUMBERS};
    
    • makes: int x[] = {10,2,3};
    • weird error line numbers later on tho

Enumerated type

==================== For the times that you don’t need anything else other than what you put inside

Initialize:

==============

typedef enum{ INDIV, OUNCE, POUND } quantity;

To set the value: quantity quantityType = INDIV;

To do somethign:

if (quantityType == INDIV){
    blah blah
}

Line buffering:

=================

storing/scanning an amount of information before something is done to it

File I/O:

===========

  • Print out data from the file:
      char buffer[1000];
      while(fgets(buffer, 1000, pFile) != NULL){
          printf("%s", buffer);
      }
      //OR
      while(fscanf(pFile, "%s", buffer) == 1) 
    
    • returns # other than 1 if it doesn’t pass a string
  • Print directly to the file:
      fputs("Messing with strings", pFile);
    
    • pFile is the way you are entering stuff
  • TO PRINT WHOLE THING, YOUR “CURSOR” HAS TO BE AT BEGINNING

  • To get number of bytes in whole file:
      fseek(pFile, 0, SEEK_END);
      ftell(pFile)
    
    • because the “cursor” is at the end of the file
  • see Functions

Convert any base to any base:

===============================

For startingBase, endingBase, numberToConvert

  • numberToConvert % endingBase => put in array
  • Then numberToConvert = (numberToConvert - <remainder>) / endingBase
    • and so on until you get an error with 1

Convert any base to base 10:

  • ex: binary 110 to base 10
    • (1 * 2^2) + (1 * 2^1) + (0 * 2^0)

chars have values, too!

if(isalpha(number[i])){
    int charCode = ((int)tolower(number[i])) - 87;
    result += charCode * pow(baseFrom, toThePowerOf);
}

Bitwise operators:

====================

& And bitwise operator:

  • 110 & 111 => 1 for every time they’re both 1
    • 110 is result

| Or bitwise operator:

  • 6 | 7 => if either is a 1, return a 1 => 111

^ exclusive or:

  • 6 ^ 7
    • 1 returned if one is a 1, other is 0
    • 001 => 1 is returned

~ bitwise not:

  • ~x
    • if a bit in x == 0, that bit is now = 1
    • if a bit in x == 1, that bit is now = 0
  • negative is the 2’s complement 000000010 => 2 111111101 => complement of 2 111111110 => add 1 to it

  • inverse sign = ~
    • Ex: ~numberSix = -6
  • shift operators:
    • shiftLeftTwo = numberSix << 2;
    • x/pow(2, n) is the same as x>>n
  • bit masking
    • if you want to see what is in some specific spots
    • do 1 for parts you want to see, 0 for others
    • do an AND bitwise operator

Functions:

============

printf("string, int %d, long int %ld, decimal with 2 decimal

  • places shown %.2f”, intValue, longIntValue, floatValue);
  • Displays to terminal
  • Conversion characters:
    • %ld //long
    • %d //int
    • %.5f //prints to 5 decimal places
    • %.15f //used for float and double
    • %c //char
    • %s //string
    • %p //return hexidecimal addresses //also use & => printf(“%p”, &rand1)
  • \n = line, \t = tab, \\ = print, \" = print “

scanf("<data type in format>", &whereToStore, &otherPlace);

  • Ex: scanf(" %d/%d/%d", &month, &day, &year);
  • Store input from user, bulky
  • will overwrite values if there is a data overflow
  • needs the &
  • don’t use %d++ in the “” because it screws up
  • will return a 1 or 0 if compared with == to a number

fgets(storeHere, 30, stdin);

  • like scanf()
  • store the 30 bytes of information in storeHere through stdin
  • adds the \0 character
  • adds new line
  • accepts more than one string

fputs("string here", stdout);

  • string, output method
  • no new line

gets(name);

  • accepts one string and puts it in name
  • no new line. It ends with \0

puts("string here");

  • makes a new line after displaying the string

strcpy(myName, "Bob Joe"); //used to hold "Derek Banas"

  • assign a different value to the variable

strcomp()

  • returns negative # if first string is less than 2nd
  • returns positive # if more (second would come first if alphabetic)
  • returns 0 if equal

strcat(yourCity, yourState);

  • combine the two strings into yourCity

strlcpy(yourCity, "aksjdfl", sizeof(yourCity));

  • cuts off the end of the string so variable doesn’t overflow

strlen(name);

  • returns the length of the variable (number of slots)

theChar = getchar();

  • Takes in chars until enter is pressed

putchar(theChar);

  • print the char on the screen

strrchr(randomString, '\n');

  • returns last occurance of \n in randomString

strchr(randomString, 'a');

  • returns first occurance of a in randomString

tolower(char)

  • makes the letter lower cased
  • Ex: theString[i] = tolower(theString[i]);

toupper(char)

  • makes the letter upper cased

isalnum(char)

  • is it consisting of all numbers?

isalpha(char)

  • alphabetic character

isblank(char)

  • space

isdigit(char)

  • digit

isgraph(char)

  • anything but space

isupper(char)

  • upper cased

islower(char)

  • lower cased

ispunct(char)

  • punctuation

isspace(char)

  • any space

strcmp(string, string)

  • comparing two string sto see if they match
  • returns 0 if they’re the same
  • returns (+) if first string more (further in alpha order)
  • returns (-) if first string is less

exit()

  • Close program. Don’t run anything else.
  • can be (0),(1),(2),(3),(4), etc for personal reference

rand()

  • Create random number
  • To get numbers 1-50: rand() % 50 + 1

break;

  • exit out of an infinite loop (is like exit())
  • used in switch

continue;

  • go back to the beginning of the braces
  • Ex:
      for(blah){ 
          //do something, start here again!
          if (variable == 1){ continue; }
          //don't do this stuff this time
      } 
    
switch(whatToDo){
        
    case(1) : printf("Print the time");
        break;

    default : printf("Bye");
        exit(0);
        break;

    }
  • if whatToDo == 1 (in case(1)), do that
  • go on to other cases
  • default is done if nothing else works
  • if there isn’t a break, it will execute all the other statements after the one it entered in on range is 4…6 instead of 4 or something

sizeof(variableName);

  • returns the number of bytes in there

pRandomNumbers = malloc(amountOfBytesToStore);

  • if fails, stores a NULL
  • Good usage to store a specific number of ints:
    • malloc(amtOfNumbersToStore * sizeof(int))

free(pRandomNumbers);

  • free memory for pRandomNumbers to prevent crashing
  • used for large scale programs that don’t end in a while

pFile* = fopen("fileName.txt", "w");

  • will make the file if it doesn’t exist
  • binary files (.bin) use things like rb+
    • “w” - stuff already inside will be deleted/replaced
    • “a” - append or add new info
    • “r” - read from the file
    • “a+” - start at end of file if it exists and reads and writes
    • “r+” - open at beginning for reading and writing, no delete, no make new file
    • “w+” - delete original (or make new one if no exist), read and write
  • if file wasn’t opened, returns a 1

fprintf(pFile, "%d", randomNumber)

  • print it to the file like printf()
  • file to print to, what to print

fclose(pFile)

  • close the file, if not closed, returns 0
  • if went well, returns 1
      if(fclose(pFile)) != 0){
          printf("Success writing to text");
      }
    

fseek(pFile, 12, SEEK_SET);

  • can use (-) numbers in fseek()
  • 12- move 12 characters => “moving the cursor”
  • Seek things:
    • SEEK_SET - Start from beginning of file
    • SEEK_CUR - Move from current position in file
    • SEEK_END - Based off of end of file
  • in binary mode, need to * number chars to move by the size of each thingie => move 12 => 12 * sizeof(int)

ftell(pFilfe)

  • returns the number of bytes the cursor is from the beginning of the file

perror("Error Occured");

  • prints that and the standard error message

printf("Error Code %d\n", errno);

  • prints error code

fwrite(name, sizeof(name[0]), sizeof(name)/sizeof(name[0]), pFile);

  • Write binary data to file
  • pointer by default
  • variable, size of each element, number of elements, where to print

fread(buffer, 1, fileSize, pFile);

  • dataInFile = fread(blah blah);
  • information goes to buffer, bytes taken from each element,
    • number of elements, read from this place

rewind(pFile);

  • go to beginning of file

pow(base, toThePowerOf);

  • mutiply base and itself toThePowerOf times
Tags: coding_notes