Вы находитесь на странице: 1из 16

Memory functions

Malloc() and free()


#include <stdio.h>
#include <stdlib.h>
void main()
{
int *nums = malloc(sizeof(int)*5); //Dynamically allocate a contiguous memory
space from the heap to store 5 integers. The sizeof() function is used because
different computers tore data variables differently.
for (int i = 1; i <= 5; i++)
{
nums[i] = i;
printf("%i\n", nums[i]);
}
free(nums); //frees the memory held by nums
return 0;
}
Memcpy()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
int nums[] = {1,2,3,4,5};
int *nums2 = malloc(sizeof(int)*5);
memcpy(nums2, nums, sizeof(int)*5); //The first parameter is the destination,
then the source and finally the amount of memory to copy.
for (int i = 0; i < 5; i++)
printf("%i\n", nums2[i]);
free(nums2);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{

char myString[] = "Adam likes dogs"; // This is created on the stack which is a RW
part of memory.
char *name = "Rick"; // This is on the RO data segment. So if we edit this then
this will first be copied
to the stack and then edited which is much slower.
//memcpy(&myString[0], name, sizeof(char)*4); --- This also works
memcpy(myString, name, sizeof(char)*4);
printf("%s\n", myString);
return 0;
}
Memset()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
int *nums = malloc(sizeof(int) * 5);
memset(nums, 0, sizeof(int) * 5); //memset() sets a value (0) to a certain amount
of memory at a certain place in memory.
return 0;
}
Memcmp()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
int nums1[] = {1,2,3,4,5,6};
int nums2[] = {1,2,3,4,5,6};
if (memcmp(nums1, nums2, sizeof(nums1)) == 0) //memcmp() takes two chunks
of memory (nums1 and nums2 here) and compare them for a given amount of size.
//sizeof(nums1) will not work if it is created in the heap using malloc() or
something similar.
printf("They are equal\n");
else
printf("They are not equal\n");
return 0;
}
Realloc()
This function is used to reallocate the amount of memory allocated from something
from heap using malloc.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char *characters = malloc(sizeof(char) * 10);
for (int i =0; i < 5; i++)
characters[i] = i + 65; //65 is the numerical value for A. In the first run, i = 0
so A is stored in the first place. In the second run i = 1, so 1+65 = 66 or B is stored
and so on.
for (int j = 0; j < 5; j++)
printf("%c\n", characters[j]);
characters = realloc(characters, sizeof(char) * 5); // realloc() returns a new block
of 5 chars at a new location.
free(characters);
return 0;
}
Reading from files
All file related programs are in stdio.h.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
//The following piece of code opens a file and reads the first character
FILE *file = fopen("F:\\Studies\\Programming\\My Programming
Notes\\Example.txt", "r"); //The fopen() function opens a file in read mode. The
other modes are append, write and so on. The mode argument is passed as a
string. It creates a file structure in memory and returns a FILE type pointer to that
structure.
printf("%c\n", fgetc(file)); //fgetc() reads the first character in the file.
fclose(file); //Close the file.
//In this case, we are going to read the entire file. The reason to close and reopen
the file again is make fgetc() read from the beginning again.
file = fopen("F:\\Studies\\Programming\\My Programming Notes\\Example.txt",
"r"); //The file pointer is simply re-used.
char c;
do
{
c = fgetc(file);
printf("%c", c);

}
while (c != EOF); //fgetc() returns an EOF constant when it reaches the end of the
file.
fclose(file);
return 0;
}
Fscanf()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*The file Example2.txt contains the total number of entries at the top. In each line
the first number denotes the number of characters in each name, then the name
and then a score.*/
//The next structure is designed to hold the data - name and score - from the file in
a structure.
typedef struct
{
char *name;
int score;
} Entry;
void main()
{
FILE *file = fopen("F:\\Studies\\Programming\\My Programming
Notes\\Example2.txt", "r");
int entryCount; //This variable is used to decide how much memory needs to be
assigned in heap for the structure.
fscanf(file, "%i", &entryCount);
Entry *entries = malloc(sizeof(Entry) * entryCount);
for (int i = 0; i < entryCount; i++) //This for loop fills up the structure by reading
from the file.
{
int nameLen; //This variable is used to decide the amount of memory in
heap required to hold each name.
fscanf(file, "%i", &nameLen);
entries[i].name = malloc(sizeof(char) * (nameLen + 1));
fscanf(file, "%s %i", entries[i].name, &entries[i].score);
printf("%i. %s - %i\n", i+1, entries[i].name, entries[i].score);
}
//Memory clean up

fclose(file);
for (int i = 0; i < entryCount; i++)
free(entries[i].name);
free(entries);
return 0;
}
Fputc() and fputs()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
FILE *file = fopen("F:\\Studies\\Programming\\My Programming
Notes\\WriteTest.txt", "w"); //In the write mode, the file will be created if it doesn't
exist. If it exists then it will be overwritten.
fputc('G', file); //Writes a single character to the file.
fclose(file);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
FILE *file = fopen("F:\\Studies\\Programming\\My Programming
Notes\\WriteTest.txt", "w");
fputs("This is good", file);
fclose(file);
return 0;
}
Fprintf()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
FILE *file = fopen("F:\\Studies\\Programming\\My Programming
Notes\\Student.txt", "w"); //The student.txt file got created.
int studentCount;
printf("How many students are there?\n");
scanf("%i", &studentCount);

fprintf(file, "%i\n", studentCount);


for (int i = 0; i < studentCount; i++)
{
char studentName[30] = {0};
float gpa;
printf("What is the student's last name?\n");
scanf("%s", studentName);
printf("What is the student's gpa?\n");
scanf("%f", &gpa);
fprintf(file, "%i\t%s\t%.2f\n", strlen(studentName), studentName, gpa);
}
fclose(file);
return 0;
}
Editing a text file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*In case of editing a file, a new temp file is created and then renamed as the
original file, after the original has been removed.*/
//This struct will hold the name and gpa of the passing students.
typedef struct
{
char *name;
float gpa;
} student;
void main()
{
FILE *originalFile = fopen("F:\\Studies\\Programming\\My Programming
Notes\\Student.txt", "r");
FILE *newFile = fopen("F:\\Studies\\Programming\\My Programming
Notes\\Student_temp.txt", "w");
int studentCount;
fscanf(originalFile, "%i", &studentCount);
student *passingStudents = malloc(sizeof(student) * studentCount); //Creating
the passingStudents structure.
int passingCount = 0;
int nameLen;

//This for loop reads from the original file and fills the passingStudents structure.
for (int i = 0; i < studentCount; i++)
{
fscanf(originalFile, "%i", &nameLen);
char *name1 = malloc(sizeof(char) * (nameLen + 1));
name1[nameLen] = '\0';
float gpa1;
fscanf(originalFile, "%s %f", name1, &gpa1);
if (gpa1 >= 6.50)
{
passingStudents[passingCount].name = name1;
passingStudents[passingCount].gpa = gpa1;
passingCount++;
}
}
fprintf(newFile, "%i\n", passingCount); //Add the number of passing students.
for (int i = 0; i < passingCount; i++) //Fill up the new file from the structure.
fprintf(newFile, "%i\t%s\t%.2f\n", strlen(passingStudents[i].name),
passingStudents[i].name, passingStudents[i].gpa);
fclose(originalFile);
fclose(newFile);
remove("F:\\Studies\\Programming\\My Programming Notes\\Student.txt");
rename("F:\\Studies\\Programming\\My Programming Notes\\Student_temp.txt",
"F:\\Studies\\Programming\\My Programming Notes\\Student.txt");
return 0;
}
Appending text to a file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
FILE *file = fopen("F:\\Studies\\Programming\\My Programming
Notes\\Example.txt", "a"); //It will create the file.
fputs(" This is just getting better.", file);
fclose(file);

return 0;
}
Itoa()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
int num = 53;
char str[10] = {0};
itoa(num, str, 10);
printf("%s\n", str);
return 0;
}
Sprintf()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char fstr[30] = {0};
sprintf(fstr, "%i %.2f %c", 67, 45.67, 'r'); //prints to the string fstr and not to the
screen
printf("%s\n", fstr);
return 0;
}
Converting string to number
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char *c = "582 is a number. 673";
int i = atoi(c); //This function will start reading from wherever c is pointing to and
read all the numbers till it hits something that is not a number. Thus 673 is ignored.
int j = atoi(&c[17]); //17 is the index in c where 6 is located.
printf("%i\t%i\n", i,j);
return 0;

}
Time functions
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<string.h>
<time.h>

void main()
{
time_t currentTime; //Time in C is stored in a time_t struct
time(&currentTime); //time() gets the current time of the system and stores in the
currentTime struct
printf("%s\n",ctime(&currentTime)); //The right-arrow is used to access individual
fields in the struct.
return 0;
}

#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<string.h>
<time.h>

void main()
{
time_t currentTime; //Time in C is stored in a time_t struct
time(&currentTime); //time() gets the current time of the system and stores
in the currentTime struct
/*In the next line we convert the struct of type time_t to a struct of type
tm. This is done so that we can access the different fields of the struct.
The function that does this is the localtime() function.
myTime is defined as a pointer because the localtime function returns a
pointer.*/
struct tm *myTime = localtime(&currentTime);
printf("%i\n",myTime->tm_mon+1); //The right-arrow is used to access
individual fields in the struct. C by default starts the month from 0, so the +1
gives the correct month integer.
return 0;
}
Timing execution time
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <time.h>
void main()
{
for (int i = 0; i < 10000000; i++);
int ticks = clock(); //clock() measures how many ticks the program executed for.
printf("%i\n", ticks);
printf("%f\n", (float)ticks/CLOCKS_PER_SEC); //CLOCKS_PER_SEC is a constant that
gives ticks per second.
return 0;
}
Storing functions as variables
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<string.h>
<time.h>

//The original function add and mul need to be defined first.


int add(int a, int b)
{
return a + b;
}
int mul(int a, int b)
{
return a*b;
}
//Here the first parameter of the printResult function can be any function that has
two integer arguments and the arguments of that function.
void printResult(int (*someFunction2)(int, int), int arg0, int arg1)
{
printf("The value is %i\n", someFunction2(arg0, arg1));
}
int main()
{
//This is how a function is set up as a variable. The first 'int' is the return type of
the function. someFunction is the reference name. And this is followed by a list of
the type of each argument.
int (*someFunction1)(int, int) = add;
printf("The addition is %i\n", someFunction1(6,7));
printResult(mul, 6, 7);
return 0;
}

The generic pointer (void *)


It can point to anything an integer, a float, a struct etc.
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<string.h>
<time.h>

typedef struct
{
int num, denom;
char *name;
} fraction;
int main()
{
int i = 7;
float f = 3.9;
fraction fract = {5, 6, "Adam"};
void *myPointer = &i;
printf("%i\n", *(int*)myPointer); //Dereferencing void pointers are not allowed
because the compiler has no idea what the generic pointer holds. So in this case we
are casting it as an int pointer to print out the content.
return 0;
}
Generic swap function
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<string.h>
<time.h>

//Using generic pointers to create a generic swap function.


void genericSwap (void *a, void *b, size_t size)
{
void *temp = malloc(size);
memcpy(temp, a, size);
memcpy(a, b, size);
memcpy(b, temp, size);
free(temp);
}
typedef struct
{
int num, denom;
}fraction;

int main()
{
//Testing the generic swap on structs
fraction fract1 = {5, 6};
fraction fract2 = {2, 3};
printf("Before fract1 = %i/%i, fract2 = %i/%i\n", fract1.num, fract1.denom,
fract2.num, fract2.denom);
genericSwap(&fract1, &fract2, sizeof(fraction));
printf("After fract1 = %i/%i, fract2 = %i/%i\n", fract1.num, fract1.denom,
fract2.num, fract2.denom);
//Testing the same generic swap function on characters
char c1 = 'a';
char c2 = 'b';
printf("%c, %c\n", c1, c2);
genericSwap(&c1, &c2, sizeof(char));
printf("%c, %c\n", c1, c2);
return 0;
}
Linear Search with Integers
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<string.h>
<time.h>

//Searches through an array and returns the index of the element key in the array.
Returns -1 if the key is not found.
int linearSearch(int *array, int len, int key)
{
for(int i = 0; i < len; i++)
{
if (array[i] == key)
return i;
}
return -1;
}
int main()
{
int nums[5] = {5, 8, 19, 45, 23};
printf("%i\n", linearSearch(nums, 5, 19));
return 0;

}
Generic Linear Search
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<string.h>
<time.h>

//Since a generic pointer is used, the size needs to be passed as well. And the
function required to compare that data type since generic pointers cannot be
dereferenced.
int glinearSearch(void *array, size_t elemSize, int len, void *key, int(*cmp) (void *a,
void*b))
{
for(int i = 0; i < len; i++)
{
void *currentElem = array + (elemSize * i);
if (cmp(currentElem, key) == 0)
return i;
}
return -1;
}
typedef struct
{
int num, denom;
} fraction;
int fractCompare (fraction *f1, fraction *f2) //This function will be passed as
int(*cmp) (void * a, void *b). The fraction *f1 and fraction *f2 arguments are alright,
since generic pointers are implicitly casted.
{
//The fractions are converted to floats so that 1/2 and 8/16 can be evaluated as
equal.
float f1val = (float)f1->num/(float)f1->denom; //The casting as floats are done to
avoid errors of integer division. For example, in integer division, 1/2 = 0.
float f2val = (float)f2->num/(float)f2->denom;
if (f1val == f2val)
return 0;
else
return 0xBeef;
}
int main()
{
fraction fract[5] = { {1,4}, {3,5}, {2,5}, {1,3}, {8,16} };
fraction key = {1,2};

int index = glinearSearch(fract, sizeof(fraction), 5, &key, fractCompare);


printf("%i\n", index);
return 0;
}
Binary Search Algorithm with Integer Array
The binary search needs the array to be already sorted. But once the array is
sorted, it is much faster than linear search.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//The funda of binary search is to break the array down into two parts, compare the
key to the middle element of the array. If the key is larger then repeat the process
with the right side of the array. If the key is smaller then repeat the process with the
left side of the array.
int binarySearch(int *array, int len, int key)
{
int low = 0, high = len - 1, currentIndex; //low points to the starting element and
high points to the last element. currentIndex for the moment points to roughly the
middle element.
while (low <= high)
{
currentIndex = (int)(high - low)/2;
if(array[currentIndex] = key)
return currentIndex;
else if (array[currentIndex] > key)
high = currentIndex;
else if (array[currentIndex] < key)
low = currentIndex;
}
return -1;
}
int main()
{
int arr[8] = {2, 3, 5, 9, 12, 16, 21, 34};
printf("%i\t%i\n", binarySearch(arr, sizeof(arr), 10), binarySearch(arr, sizeof(arr),
21));
}
Generic binary search algorithm
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int gbinarySearch(void *array, size_t elemsize, int len, void *key, int(*cmp)(void *a,
void*b))
{
int low = 0, high = len - 1, currentIndex;
while (low <= high)
{
currentIndex = (high+low)/2;
void *currentElem = array + (currentIndex * elemsize);
if (cmp (key, currentElem) == 0)
return currentIndex;
else if (cmp(key, currentElem) < 0)
high = currentIndex;
else
low = currentIndex;
}
return -1;
}
typedef struct
{
int num, denom;
} fraction;
int fractCompare (fraction *f1, fraction *f2)
{
float f1val = (float)f1->num/(float)f1->denom;
float f2val = (float)f2->num/(float)f2->denom;
return (f1val - f2val) * 100; //This is a positive value when f1val > f2val and so on.
The multiplication by 100 is used because the return type of the function in int.
}
int main()
{
fraction fracts[6] = {{1,2}, {2,3}, {3,4}, {5,6}, {4,7}, {6,9}};
fraction key = {9,12};
int index = gbinarySearch(fracts, sizeof(fraction), 6, &key, fractCompare);
printf("%i\n", index);
}

Recursion
Writing a recursive function to add the digits of an integer.
#include <stdio.h>
#include <stdlib.h>

#include <string.h>
int sumDigits(int);
int main()
{
int n = 12346;
printf("%i\n", sumDigits(n));
}
int sumDigits(int a)
{
if (a == 0)
return 0; //This is the breakout condition of the program.
int s, new_num;
s = a % 10; //This takes out the last digit.
new_num = a / 10; //This creates a new integer without the last digit.
return s + sumDigits(new_num);
}

Вам также может понравиться