#include #include // Imports NAN (Not a Number) /* This program performs various truthy/falsey tests in C. To compile this program on cs.wellesley.edu (tempest): gcc -o truthyFalsey truthyFalsey.c To run the compiled program: ./truthyFalsey Your goal is to relate the results of these tests to the C language specification. *Why* are the results the way they are? */ // Sample function that determines if float is negative. // Since C has no boolean type, returns an int. // This function is used in tests below int isNeg (float f) { return f < 0.0; } // main() is the function that's run when a C program is executed int main() { // char* means "pointer to char", which is a C string char* T = "truthy"; char* F = "falsey"; // ---------- Integer tests ---------- printf("Integer %d is %s\n", 17, 17 ? T : F); printf("Integer %d is %s\n", 0, 0 ? T : F); printf("Integer %d is %s\n", -3, -3 ? T : F); // ---------- Float tests ---------- printf("Float %f is %s\n", 3.141, 3.141 ? T : F); printf("Float %f is %s\n", 0.000, 0.000 ? T : F); // NAN is the special "Not a number" float value printf("Float %f is %s\n", NAN, NAN ? T : F); // ---------- Character tests ---------- printf("Char '%c' is %s\n", 'a', 'a' ? T : F); printf("Char '%c' is %s\n", 'B', 'B' ? T : F); printf("Char '%c' is %s\n", '0', '0' ? T : F); printf("Char '%c' is %s\n", '1', '1' ? T : F); // '\0' is the special "null character" that terminates a string printf("Char '%c' is %s\n", '\0', '\0' ? T : F); // ---------- Pointer and array tests ---------- // A C string has type char* -- i.e., it's really a pointer // to the first character of the string. // printf spec %08x prints memory addresses as 8 hex digits. printf("String \"%s\" (%08x) is %s\n", F, F, F ? T : F); printf("String \"%s\" (%08x) is %s\n", "", "", "" ? T : F); int i1 = 42; int i2 = 0; int intArray1[3] = {1, 2, 3}; // int array with nonzero in first slot int intArray2[3] = {0, 1, 2}; // int array with zero in first slot // int* means "pointer to int", i.e., address of first int in an int array int* intPtr1 = &i1; // & is "address of" operator int* intPtr2 = &i2; int* intPtr3 = (int*) intArray1; // (int*) "casts" array type to pointer type int* intPtr4 = (int*) intArray2; // NULL is the special "null pointer", which is simply address 0. // Attempts to dereference (read the value at) address 0 // (and other low memory addresss) will cause the operating system // to signal a dreaded Segmentation Fault. printf("null pointer (%08x) is %s\n", NULL, NULL ? T : F); printf("intPtr1 (%08x) is %s\n", intPtr1, intPtr1 ? T : F); printf("intPtr2 (%08x) is %s\n", intPtr2, intPtr2 ? T : F); printf("intPtr3 (%08x) is %s\n", intPtr3, intPtr3 ? T : F); printf("intPtr4 (%08x) is %s\n", intPtr4, intPtr4 ? T : F); printf("intArray1 is %s\n", intArray1 ? T : F); printf("intArray2 is %s\n", intArray2 ? T : F); printf("isNeg(3.141) is %d\n", isNeg(3.141)); printf("isNeg(-2.3) is %d\n", isNeg(-2.3)); int (*isNegPtr)(float) = &isNeg; // C's obscure way to declare a function pointer printf("function pointer isNegPtr (%08x) is %s\n", isNegPtr, isNegPtr ? T : F); printf("function isNeg (%08x) is %s\n", isNeg, isNeg ? T : F); // ---------- Struct tests ---------- // A struct is a compound values with named components; // it's sometimes called a "record" in other languages. // E.g. the struct type Point is a record with integer fields named x and y. struct Point {int x; int y;}; struct Point pt; pt.x = 1; pt.y = 2; /* // Uncomment this for testing printf("struct pt is %s\n", pt ? T : F); */ // ---------- Union tests ---------- // A union is a value that can have one of several types; // it's sometimes called a "variant" in other languages. // E.g. the union type IntOrFloat can be *either* an int or a float. union IntOrFloat {int i; float f;}; union IntOrFloat iof1, iof2; iof1.i = 17; iof2.f = 3.141; /* // Uncomment this for testing printf("union iof1 is %s\n", iof1 ? T : F); printf("union iof2 is %s\n", iof2 ? T : F); */ }