C Programming, Autumn 2013, Exercises for the Fifth Week. double maxi(double x, double y, double (*fp)(double z));

Similar documents
1 Abstract Data Types Information Hiding

Lecture 11 Doubly Linked Lists & Array of Linked Lists. Doubly Linked Lists

Coding Rules. Encoding the type of a function into the name (so-called Hungarian notation) is forbidden - it only confuses the programmer.

LINKED DATA STRUCTURES

Illustration 1: Diagram of program function and data flow

Jorix kernel: real-time scheduling

Programming languages C

Lecture 12 Doubly Linked Lists (with Recursion)

BSc (Hons) Business Information Systems, BSc (Hons) Computer Science with Network Security. & BSc. (Hons.) Software Engineering

Project 4 DB A Simple database program

Introduction to Socket Programming Part I : TCP Clients, Servers; Host information

Data Types in the Kernel

10CS35: Data Structures Using C

Object Oriented Software Design II

1) The postfix expression for the infix expression A+B*(C+D)/F+D*E is ABCD+*F/DE*++

arrays C Programming Language - Arrays

Molecular Dynamics Simulations with Applications in Soft Matter Handout 7 Memory Diagram of a Struct

Introduction to Data Structures

Embedded Programming in C/C++: Lesson-1: Programming Elements and Programming in C

Output: struct treenode{ int data; struct treenode *left, *right; } struct treenode *tree_ptr;

Stacks. Linear data structures

Lab 4: Socket Programming: netcat part

What is COM/DCOM. Distributed Object Systems 4 COM/DCOM. COM vs Corba 1. COM vs. Corba 2. Multiple inheritance vs multiple interfaces

NDK: NOVELL NSS AUDIT

Code and Usage Description. A.Konstantinov

Sistemi Operativi. Lezione 25: JOS processes (ENVS) Corso: Sistemi Operativi Danilo Bruschi A.A. 2015/2016

Short Notes on Dynamic Memory Allocation, Pointer and Data Structure

ECE 250 Data Structures and Algorithms MIDTERM EXAMINATION /5:15-6:45 REC-200, EVI-350, RCH-106, HH-139

Common Data Structures

Data Structure Reverse Engineering

CUDA Programming. Week 4. Shared memory and register

Application Note C++ Debugging

Not agree with bug 3, precision actually was. 8,5 not set in the code. Not agree with bug 3, precision actually was

Fast Arithmetic Coding (FastAC) Implementations

Tutorial on C Language Programming

sys socketcall: Network systems calls on Linux

Wireless Mesh Networks under FreeBSD

Lab 5: BitTorrent Client Implementation

Quiz 4 Solutions EECS 211: FUNDAMENTALS OF COMPUTER PROGRAMMING II. 1 Q u i z 4 S o l u t i o n s

AN AES encryption and decryption software on LPC microcontrollers. Document information

Security types to the rescue

PES Institute of Technology-BSC QUESTION BANK

PART-A Questions. 2. How does an enumerated statement differ from a typedef statement?

Analysis of a Search Algorithm

C++ Overloading, Constructors, Assignment operator

Linked Lists, Stacks, Queues, Deques. It s time for a chainge!

Passing 1D arrays to functions.

ECS 165B: Database System Implementa6on Lecture 2

Data Structures Using C++ 2E. Chapter 5 Linked Lists

CSE 333 SECTION 6. Networking and sockets

Demonstrating a DATA Step with and without a RETAIN Statement

C Programming Review & Productivity Tools

How To Write Portable Programs In C

DUOLINGO USABILITY TEST: MODERATOR S GUIDE

IT304 Experiment 2 To understand the concept of IPC, Pipes, Signals, Multi-Threading and Multiprocessing in the context of networking.

Implementation Aspects of OO-Languages

Comp151. Definitions & Declarations

Supplemental Worksheet Problems To Accompany: The Pre-Algebra Tutor: Volume 1 Section 1 Real Numbers

7th Marathon of Parallel Programming WSCAD-SSC/SBAC-PAD-2012

TivaWare USB Library USER S GUIDE SW-TM4C-USBL-UG Copyright Texas Instruments Incorporated

CORBA Programming with TAOX11. The C++11 CORBA Implementation

16 Collection Classes

Top 10 Bug-Killing Coding Standard Rules

Preparing and Revising for your GCSE Exams

M-way Trees and B-Trees

CS104: Data Structures and Object-Oriented Design (Fall 2013) October 24, 2013: Priority Queues Scribes: CS 104 Teaching Team

First Java Programs. V. Paúl Pauca. CSC 111D Fall, Department of Computer Science Wake Forest University. Introduction to Computer Science

Example 1/24. Example

An Overview of Java. overview-1

PharmaSUG Paper QT26

3.5. cmsg Developer s Guide. Data Acquisition Group JEFFERSON LAB. Version

KITES TECHNOLOGY COURSE MODULE (C, C++, DS)

ADTs,, Arrays, Linked Lists

Lab 6: Building Your Own Firewall

Design and Implementation of Netdude, a Framework for Packet Trace Manipulation

Java from a C perspective. Plan

An Incomplete C++ Primer. University of Wyoming MA 5310

Specific Simple Network Management Tools

Splicing Maps and Sets

Lecture Notes on Binary Search Trees

Masters programmes in Computer Science and Information Systems. Object-Oriented Design and Programming. Sample module entry test xxth December 2013

Lecture 22: C Programming 4 Embedded Systems

1 Description of The Simpletron

Operating Systems and Networks

The University of Alabama in Huntsville Electrical and Computer Engineering CPE Test #4 November 20, True or False (2 points each)

The Linux Kernel Device Model

The Payroll Program. Payroll

Data Structures and Algorithms!

Assignment 5: Adding and testing a new system call to Linux kernel

Porting applications & DNS issues. socket interface extensions for IPv6. Eva M. Castro. ecastro@dit.upm.es. dit. Porting applications & DNS issues UPM

Master of Sciences in Informatics Engineering Programming Paradigms 2005/2006. Final Examination. January 24 th, 2006

File Sharing. Peter Lo. CP582 Peter Lo

Seriously Simple Sums! Vedic Maths Free Tutorial. Maths Tips and Tricks to Improve Your Math Abilities

CS107L Handout 04 Autumn 2007 October 19, 2007 Custom STL-Like Containers and Iterators

Unordered Linked Lists

A deeper look at Inline functions

3 - Lift with Monitors

MatrixSSL Developer s Guide

MQX Lite Real-Time Operating System User Guide

CSCE-608 Database Systems COURSE PROJECT #2

Transcription:

C Programming, Autumn 2013, Exercises for the Fifth Week 1. Wite a function double maxi(double x, double y, double (*fp)(double z)); which takes three parameters, two double values x and y, and a pointer to a function. The function has a double value as its parameter and it returns a double value. The function maxi returns the larger of the function values (*fp)(x) and (*fp)(y). Test your function with various parameter functions. 2. Write a function int comparegen(const void *block1, const void *block2, size_t elemsize, size_t block1size, size_t block2size, int (*compareit)(const void * const void *)); which performs a lexicographical comparison of the two blocks. This function returns the value of compareit when there is a differing element. Otherwise it return -1, 0 or 1, depending on blocksizes. The given blocksize parameters are given as bytes, as is element size. Test your program using various types of blocks. 3. Write a function void printgen(const void * block, size_t elemsize, size_t blocksize, void (*printit) (const void *)); which prints all the elements in the block using the callback function printit. Test your program with various types, for example a block of doubles and a block of pointers to doubles. Intrusive Linked List Because you guys like linked lists so much, we decided to give you another one to implement. :) Let s build an intrusive linked list. An intrusive linked list is an awesome data structure that does not contain data (also called payload) in its nodes. Nodes constist only of pointers to next and prev nodes. typedef struct intrusivelistnode { struct intrusivelistnode *next; struct intrusivelistnode *prev; } IntrusiveListNode; 1

You might wonder how to use this list for anything. Well, intrusiveness here means that the list nodes themselves are part of the data that are added to the list. This makes intrusive lists also generic, since the nodes do not really care to what kind of data they belong to. If one wanted to add integers to an intrusive list, this could be done via a wrapper struct such as this: typedef struct wrapint { int i; IntrusiveListNode node; } WrapInt; In addition to the actual data, we want a list type that contains the pointer to the first element. To make operations nice an easy, we use a headered cyclic doubly linked list. This means that we do not have to take into account any nasty special cases! In case you have forgotten, a headered linked list is a linked list where the first node is not a node with any real data, and a cyclic doubly linked list is a list where the last node s next pointer points to the first element (here the header), and the prev pointer of the first node (here the header) points to the last node. Here is the list struct used in this exercise: typedef struct intrusivelist { IntrusiveListNode header; } IntrusiveList; 4. Now implement function create_intrusive_list() which allocates memory for the list and returns a pointer to that list. Remember to intialize the header node as it should be in a cyclic doubly linked list. 5. Now let s implement add_node(intrusivelist *list, IntrusiveListNode *node) which takes a node and adds it to the front of the list. Remember that the list is cyclic, and be careful not to do weird things to the header node (this node should be inserted to the right side of the header node). 6. Now to do things with the list we also need to implement remove_node(intrusivelist *list, IntrusiveListNode *node) which removes a given node from the list. Here you should note that since our list is cyclic and headered, you don t need to worry about special cases when updating links. You can simply update next and prev pointers of the appropriate prev and next nodes. 2

7. Now that we have all basic list operations implemented, let s add actual integers. We ll do this by adding the WrapInt structures introduced before. Implement function add_int(intrusivelist *list, int i) that takes as parameter and int value that is wished to add to the list. The function should allocate memory for a WrapInt structure, and add the int to it s appropriate field. This structure should then be added to the list. Adding this structure to the list is done by adding the node of the struct with the operation add_node we just implemented. This may seem weird at first, but you will understand how to access the data very soon. Now let s address the headache of how to access this data. This might seem like an awfully unclear or impossble operation. Well, C has a cool macro called offsetof, which gives the offset in memory (in bytes) of a field of struct with respect to the address of the struct itself. We do not need to use this macro, however. Instead a macro called container_of (stolen and modified from the linux kernel) is given, which uses offsetof: #define container_of(ptr, type, member) (type*)((char*)(ptr) - offsetof(type, member)) This macro returns a pointer to the the wrapping struct (typedefed in this exercise, do not get confused). It is given a pointer to the node whose corresponding value you wish to access, the name of the struct (or in our case we can and should use the typdefed name) as a word, not a string and the name of the field containing the node again not as a string. In this case, that field is called node. Let s use these concepts that we just learned. 8. Now that you know how to access data from nodes, let s implement the function remove_int(intrusivelist *list, int r) which seeks for a node in the list containing a value equal to r. If there are multiple occurrences, it is enough to remove the first of these. Hint: you know that you have searched the entire list, when the node you are currently inspecting points to the header as the next node. In case it is unclear how container_of should be used, here is an example: WrapInt *wi = container_of(list->header.next, WrapInt, node). This call to container_of returns the pointer to the WrapInt struct of the first node in the list. Now to further demonstrate what is so cool about this list and also to introduce the important concept of union, let s add ints and doubles to the same list. We will wrap these types in Numeric, which is a union type. A union type is a type that reserves enough memory to fit the largest possible value it should hold. These values are defined inside the union block. In a union typedef union numeric { int i; double d; } Numeric; 3

a variable of that union type can be used as both integer and double. Here is an example of usage. 4

Numeric num; num.i = 10; printf(%i", num.i); // This prints 10 num.d = 10.1; // pritnf("%i", num.i); // This prints 858993459 printf("%lf", num.d); // This prints 10.100000 So you see that by using the correspondingly typed field of the union, we treat the union variable as a variable of that type. Note that just like in the example if you assign to any field of a union type, values of all types will be affected, since they use the same block of memory. Now we can wrap this union type in a wrapper that also contains an extra field called type, which contains an identifier of the type of the variable that the union should be treated as. This frees the programmer from headaches when trying to figure out what was the type of this node s value. Possible types are defined in macros INT TYPE and DOUBLE TYPE in the header file. To save some memory, we ll put these in an uint8_t field. Here is the wrapping struct also found in the header file: typedef struct wrapnumeric { uint8_t type; Numeric num; IntrusiveListNode node; } WrapNumeric; 9. Let s implement a function add_numeric(intrusivelist *list, Numeric numi uint8_t type) that allocates memory to a WrapNumeric strucutre and adds it to the list, much in the same way as with add_int. Remember to also set given type in the allocated wrapper. By checking the type from the type field, we can infer as which type (int or double) we should treat each element in the list. Let s practice the use of this, and the union type by implementing two functions: one for computing the sum of all int variables in the list, and another for computing the sum of all double variables in the list. 10. Implement functions int_sum(intrusivelist *list) and double_sum(intrusivelist *list). These function should go through each element in the list. Again you can conclude that the whole list has been gone through once you are back to the header node. Now for each value you have to check what is the type of the value corresponding to each node. This can be done by checking the type field of the struct that you access via container_of. If the node is of the correct type, then you can include the value of the union type (as that type) in the sum. Now you should know something about intrusive lists, which are a good way to produce generic lists. Intrusive lists are useful because they keep memory allocation away from the actual list operations. Also it does not involve expensive 5

copying operations, when adding new nodes. You should also know something about union types. If you are still confused about union types, have a look at for example http://www.tutorialspoint.com/cprogramming/c unions.htm 6