C Basics


Collapse Content
// Single-line comments start with // - only available in C99 and later.

  /*
Multi-line comments look like this. They work in C89 as well.
  */

/*
Multi-line comments don't nest /* Be careful */  // comment ends on this line...
*/ // ...not this one!

  // Constants: #define <keyword>
#define DAYS_IN_YEAR 365

  // Enumeration constants are also ways to declare constants.
  enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
// MON gets 2 automatically, TUE gets 3, etc.

// Import headers with #include
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// (File names between <angle brackets> are headers from the C standard library.)
// For your own headers, use double quotes instead of angle brackets:
//#include "my_header.h"

// Declare function signatures in advance in a .h file, or at the top of
// your .c file.
void function_1();
int function_2(void);

// Must declare a 'function prototype' before main() when functions occur after
// your main() function.
int add_two_ints(int x1, int x2); // function prototype

// Your program's entry point is a function called
// main with an integer return type.
int main() {
  // print output using printf, for "print formatted"
  // %d is an integer, \n is a newline
  printf("%d\n", 0); // => Prints 0
  // All statements must end with a semicolon
} // end main function

Types

// ints are usually 4 bytes
int x_int = 0;

// shorts are usually 2 bytes
short x_short = 0;

// chars are guaranteed to be 1 byte
char x_char = 0;
char y_char = 'y'; // Char literals are quoted with ''

// longs are often 4 to 8 bytes; long longs are guaranteed to be at least
// 64 bits
long x_long = 0;
long long x_long_long = 0;

// floats are usually 32-bit floating point numbers
float x_float = 0.0f; // 'f' suffix here denotes floating point literal

// doubles are usually 64-bit floating-point numbers
double x_double = 0.0; // real numbers without any suffix are doubles

// Integral types may be unsigned.
unsigned short ux_short;
unsigned int ux_int;
unsigned long long ux_long_long;

// chars inside single quotes are integers in machine's character set.
'0'; // => 48 in the ASCII character set.
'A'; // => 65 in the ASCII character set.

// sizeof(T) gives you the size of a variable with type T in bytes
// sizeof(obj) yields the size of the expression (variable, literal, etc.).
printf("%zu\n", sizeof(int)); // => 4 (on most machines with 4-byte words)


// If the argument of the `sizeof` operator is an expression, then its argument
// is not evaluated (except VLAs (see below)).
// The value it yields in this case is a compile-time constant.
int a = 1;
// size_t is an unsigned integer type of at least 2 bytes used to represent
// the size of an object.
size_t size = sizeof(a++); // a++ is not evaluated
printf("sizeof(a++) = %zu where a = %d\n", size, a);
// prints "sizeof(a++) = 4 where a = 1" (on a 32-bit architecture)

Operators

// Shorthands for multiple declarations:
  int i1 = 1, i2 = 2;
  float f1 = 1.0, f2 = 2.0;

  int b, c;
  b = c = 0;

  // Arithmetic is straightforward
  i1 + i2; // => 3
  i2 - i1; // => 1
  i2 * i1; // => 2
  i1 / i2; // => 0 (0.5, but truncated towards 0)

  // You need to cast at least one integer to float to get a floating-point result
  (float)i1 / i2 // => 0.5f
  i1 / (double)i2 // => 0.5 // Same with double
  f1 / f2; // => 0.5, plus or minus epsilon
  // Floating-point numbers and calculations are not exact

  // Modulo is there as well
  11 % 3; // => 2

Equality and Comparisons

  // Comparison operators are probably familiar, but
  // there is no Boolean type in c. We use ints instead.
  // (Or _Bool or bool in C99.)
  // 0 is false, anything else is true. (The comparison
  // operators always yield 0 or 1.)
  3 == 2; // => 0 (false)
  3 != 2; // => 1 (true)
  3 > 2; // => 1
  3 < 2; // => 0
  2 <= 2; // => 1
  2 >= 2; // => 1

  // C is not Python - comparisons don't chain.
  // Warning: The line below will compile, but it means `(0 < a) < 2`.
  // This expression is always true, because (0 < a) could be either 1 or 0.
  // In this case it's 1, because (0 < 1).
  int between_0_and_2 = 0 < a < 2;
  // Instead use:
  int between_0_and_2 = 0 < a && a < 2;

  // Logic works on ints
  !3; // => 0 (Logical not)
  !0; // => 1
  1 && 1; // => 1 (Logical and)
  0 && 1; // => 0
  0 || 1; // => 1 (Logical or)
  0 || 0; // => 0

  //Conditional expression ( ? : )
  int e = 5;
  int f = 10;
  int z;
  z = (e > f) ? e : f; // => 10 "if e > f return e, else return f."

Incrementing and Bits

  //Increment and decrement operators:
  char *s = "iLoveC";
  int j = 0;
  s[j++]; // => "i". Returns the j-th item of s THEN increments value of j.
  j = 0;
  s[++j]; // => "L". Increments value of j THEN returns j-th value of s.
  // same with j-- and --j

  // Bitwise operators!
  ~0x0F; // => 0xF0 (bitwise negation, "1's complement")
  0x0F & 0xF0; // => 0x00 (bitwise AND)
  0x0F | 0xF0; // => 0xFF (bitwise OR)
  0x04 ^ 0x0F; // => 0x0B (bitwise XOR)
  0x01 << 1; // => 0x02 (bitwise left shift (by 1))
  0x02 >> 1; // => 0x01 (bitwise right shift (by 1))

Be careful when shifting signed integers - the following are undefined:

  • shifting into the sign bit of a signed integer (int a = 1 << 32)
  • left-shifting a negative number (int a = -1 << 2)
  • shifting by an offset which is >= the width of the type of the LHS:
    int a = 1 << 32; // UB if int is 32 bits wide

Challenge

a*b is considered powerful if (and only if) both of the following 2 conditions are met:

  1. a*b >= 2 * (b+3)
  2. a*b >= (a+b) * 2

return whether a*b is powerful or not.

(C has no boolean type, so 1 is used for true and 0 for false.)

Please sign in or sign up to submit answers.

Alternatively, you can try out Learneroo before signing up.

Contact Us