C
Programming Test Exercises - ANSWERS:
1. What does this print?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void){
char* word = (char *) malloc(sizeof(char) * 30);
strcpy(word,"good one 123 two 456");
char wordarr[20] = "working memory";
wordarr[4] = '\0';
char suba[4];
suba[3] = '\0';
strncpy(suba,word+5,3);
suba[1] = toupper(suba[1]);
int x;
int y;
char string1[30];
char * string2 = string1;
char * string3 ;
string3 = (char *) malloc(sizeof(char) * 30);
sscanf(word,"%s%s%i%s%i",string1,string2,&x,string3,&y);
char builtBySprintf[100];
sprintf(builtBySprintf,"the first number was %i and the second number was %i\n",x,y);
printf("the value of wordarr is: %s and the length is %lu\n", wordarr, strlen(wordarr));
printf("the value of word is: %s\n",word);
printf("the value of suba is: %s\n",suba);
printf("the value of string1 is: %s \n",string1);
printf("the value of string2 is: %s \n",string2);
printf("the value of string3 is: %s \n",string3);
printf("the value of x is %i and y is: %i \n",x,y);
printf("the value of builtBySprintf is: %s \n",builtBySprintf);
printf("tricky: the value of wordarr after the null at 4 is: %s\n",wordarr+5);
}
· the value of wordarr is: ___work___ and the length is __4___
· the value of word is: __good one 123 two 456____________________________
· the value of suba is: __oNe_______
· the value of string1 is: __one_______
· the value of string2 is: __one_______
· the value of string3 is: __two_______
· the value of x is ____123_____ and y is: __456_______
· the value of builtBySprintf is: _the first number was 123 and the second number was 456
· tricky: the value of wordarr after the null at ____4_____ is: ___ng memory________
2. What does this print?
#include <stdio.h>
struct record {
int v;
int num[3];
};
int mystery(int * numbIn, int vIn, struct record * struIn );
int main(void){
int *p , *q ;
struct record spreadsheet[2];
p = &(spreadsheet[0].v);
*p = 30;
q = p;
spreadsheet[0].num[0] = *q;
p = spreadsheet[0].num;
p[2] = 22;
spreadsheet[1].num[2] = 6;
*q = 10;
spreadsheet[0].v = 11;
p++;
*(p+3) = 16;
// This was a mistake on my part. I am not sure we can count on
spreadsheet[1]num[0] to be
the next
// cell though it seems to be. I should not
have used the pointer to cross into another array.
// C happily lets you walk though memory
though
p = &spreadsheet[0].num[1];
*p = 10;
printf("the size of a spreadsheet[0].num is %lu\n",sizeof(spreadsheet[0].num));
mystery (spreadsheet[0].num, spreadsheet[1].v, &(spreadsheet[1]));
spreadsheet[1].v = mystery (spreadsheet[0].num, spreadsheet[0].v, &(spreadsheet[1]));
//What are the last spreadsheet.values of spreadsheet.v and spreadsheet.num ?
printf("last spreadsheet.value of *p is %i \n",*p);
printf("last spreadsheet.value of *q is %i \n",*q);
printf("last spreadsheet.value of spreadsheet[0].v is %i \n",spreadsheet[0].v);
printf("last spreadsheet.value of spreadsheet[1].v is %i \n",spreadsheet[1].v);
int c,countRow;
for (countRow = 0; countRow < 2; countRow++){
for (c = 0; c < 3; c++){
printf("last spreadsheet.value of spreadsheet[%i].num %i is %i\n",
countRow,c,spreadsheet[countRow].num[c]);
}
}
}
int mystery(int * numbIn, int vIn, struct record * struIn ) {
printf("the size of a numbIn is %lu. Why?\n",sizeof(numbIn));
static int z = 0; // notice it only initializes to 0 on the first call
int * pIn = numbIn;
int y = 0;
y = y + 150;
z = z + 10 + y;
pIn[1] = 100;
vIn = vIn + 60;
// vIn was never initialized but I am
adding to it.
// C usually defaults ints
to 0, but I should not have counted on that.
struIn->v = y;
struIn->num[1] = 304;
return (z);
}
· the size of a spreadsheet[0].num is ___12______
· the size of a numbIn is __8_______. Why? When the array is passed to the function, just the address is passed. The array variable, itself, in the main method has a larger size stamped on it. Inside the function, sizeof(array) only gives back the size of the pointer to the array. In main, sizeof(array) gives the size of all the contents of the array.
· the size of a numbIn is __8_______. Why?
· last spreadsheet.value of *p is __100_______
· last spreadsheet.value of *q is ___11______
· last spreadsheet.value of spreadsheet[0].v is __11_______
· last spreadsheet.value of spreadsheet[1].v is ___320______
· last spreadsheet.value of spreadsheet[0].num 0 is ___30______
· last spreadsheet.value of spreadsheet[0].num 1 is __100_______
· last spreadsheet.value of spreadsheet[0].num 2 is __22_______
· last spreadsheet.value of spreadsheet[1].num 0 is ___16______(See my oops above)
· last spreadsheet.value of spreadsheet[1].num 1 is ___304______
· last spreadsheet.value of spreadsheet[1].num 2 is ____6_____
3. Functions pass by reference and local, both array and integer and random.
Write a small program with 2 functions:
main: Create an array of 5 dice, each with a random number between 1 and 6. Also create one more integer to hold the magic number, which is also a random number between 1 and 6. Call the game function, passing it the magic number and the dice and receive back the total. Pass both the magic number and the dice array by reference. Then print the magic number, and all the dice and the total.
game: input parameters: dice array, magic number
output : total score
process: Calculate the total score by adding all the dice, but if a die equals the magic number, change the die to die +1 before adding it to the score, and add 1 to the magic number. If the magic number goes over 6, it is okay.
#include <stdio.h>
int game (int * dice, int * magic);
// note that
the instructions did not say the magic number
// had to be a pointer, but it did say
//"Pass both the magic number
and the dice array by reference
// pass by reference means to pass the
address.
int main(void){
int dice[5];
int magic;
int count;
for (count
= 0; count < 5; count++){
dice[count] = rand() % 6 + 1; // I did not seed ; rand() % 6
gives 0-5.
// add 1 to have a range of 1-6
}
magic =
rand() % 6 + 1;
// not
required to print values before, but nice to have:
printf("prior to game function magic value is %d and dice
are:\n",magic);
for
(count = 0; count < 5; count++){
printf("Dice %i is %i\n",count,dice[count]);
}
int tot = game(dice,&magic);
printf("The magic
number is now %d and the total is %d\n",magic,tot);
for
(count = 0; count < 5; count++){
printf("Dice %i is %i\n",count,dice[count]);
}
}
int game (int *diceIn, int
* magicPtr){
// you could also use int diceIn[] in place of int * diceIn
printf("dice[5] is %i\n",diceIn[5]);
int count;
int total = 0;
for
(count = 0; count < 5; count++){
if (diceIn[count] ==
*magicPtr){
printf("dice[%i] matched\n",count);
diceIn[count] = diceIn[count] + 1; // I
did not say it was okay for the die to
// exceed 6 but it is
// the referenced dice array in main is
updated
*magicPtr = *magicPtr + 1; // the referenced variable in main is updated
printf("the new magic is %i and the
new dicein[%i] is %i\n",
*magicPtr,count,diceIn[count]);
}
total = total + diceIn[count];
}
return
total; // returning a total so the game function will evaluate to the total
}
4. Read and print formatting and String comparison and decisions:
Write a small program that reads in 2 integers, 1 decimal and 2 words and 1 date in the form YY-MM-DD. The integers should be read into 2 cells of an integer array. 1 word should be created as char word[30] and the other should be created as char * word2. Print what the user entered to the screen. Then print the decimal as currency with 2 decimal places. Then print whether the words matched.
#include <stdio.h>
#include <stdlib.h>
int main(void){
int intarr[2];
char
word[50] ;
char *
word2;
word2 = (char *) malloc(sizeof(char) * 30);
// without the malloc,
scanf will crash ; need stdlib for malloc
float dec;
// I could have used time-t for
date
// this type is found in stdlib,
but we did not cover
// that, so I am using 3 ints
int month,day,year;
puts("enter 2 integers, 1
decimal and 2 words and then 1 date s YY-MM-DD");
scanf("%d%d%f%s%s%i:%i:%i",&intarr[0], &intarr[1], &dec,
word,
word2, &year,&month,&day);
// note that while intarr is an array that hold an address
// and does not need &, the
// individual cell is a value that needs &
printf("you
entered int #1 %d int #2 %d
and dec %5.2f and word %s word2 %s year %02d month
%02d day %02d\n",
intarr[0], intarr[1], dec,
word,
word2, year,month,day);
}
5. Arrays – sizes and copies and Dynamic Arrays – creating and using
Ask the user for the size of an array. Then create 2 integer arrays of the same size – one should be static and the other dynamic. (Dynamic means it is created in memory without an array name.) Fill them both with random numbers. Then look through them both to see whether they have the same contents. Print that the result of your test, stating whether the contents are the same.
#include <stdio.h>
#include <stdlib.h>
int main(void){
int arrsize, count;
int issame = 1;
puts("enter
array size");
scanf("%d",&arrsize);
int normalArray[arrsize];
int * dynArray = (int *) malloc (sizeof(int)*arrsize);
// note that dynamic array does
not have an array name
// only a pointer to the array memory
for
(count = 0; count < arrsize; count++){
normalArray[count]
= rand() % 4 ; // I did not seed ;
rand() % 6 gives 0-5.
// used range of
0 to 4
dynArray[count]
= rand() % 4 ;
// uncomment for
testing to make it the same:
// dynArray[count]
= normalArray[count] ;
}
count =
0;
while (issame == 1 && count < arrsize)
{ //keep looking
through the array as long
// as issame is not proven false
if (normalArray[count] != dynArray[count]){
count = arrsize ; // done to end
the loop
issame = 0; // issame
is false
}
count = count +1;
}
if (issame == 0){
puts("The contents are not the same");}
else {
puts ("The contents are the same");}
// not required but needed for
testing
for
(count = 0; count < arrsize; count++){
printf("normalArray[%i] is %i and DynArray[%i] is %i\n",
count,normalArray[count], count,dynArray[count]);
}
}
6. Questions about string functions:
a) What is the difference between char * and char [ ].
char * allocates only the space for a pointer (the size of an
address) while char x[] creates an array of characters that allocates space for
the entire array.
b) When do you need to use free?
After you have used
malloc
c) Given the variables zip_code_first_five, zip_code_last_four and city and state, write a sprintf command that will put these variable values into the variable address_line_2 in city, state xxxxx-xxxx (with the last part being zip_code_first_five - zip_code_last_four ) format.
sprintf(address_line_2,"%s,
%s %05d-%04d",
city,state,zip_code_first_five,zip_code_last_four);
printf("%s",address_line_2);
d) Given the string word containing "1 good 3", write a sscanf command that will extract the 1, good and 3 from the string word into two integer variables x and y and one character array myword.
sscanf(word,"%d,good,%d",&x,&y);
e) Write a typedef statement that creates a new variable type Stringy that is actually just a pointer to a character.
typedef char * Stringy
7. Structure – declare and use as a function parameter
Main:
· Make a structure of pets that will hold a pet name, type and age. It should include the name of the pet, the type of pet (such as dog or cat) and the age of the pet. A pet type can only be 10 characters long but its name can be 20 characters long.
· Ask the user how many pets they have, and then create an array of the number of pets they mentioned.
· Ask the user for the name, type and age of each pet.
· Create one more structure variable of a single pet.
· Call the findBestPet function and then print the single pet variable values.
findBestPet
· takes in the array of pets and a pointer to the single pet. It should ONLY read through all the pets and find the oldest. Copy the values of the oldest pet into the single pet structure variable.
#include <stdio.h>
struct Pets {
char
name[21];
char
type[11]; // note 11 for the 10 char type + 1 char null
int age;};
void findBestPet( struct Pets petArrayIn[], int size, struct Pets * bestPetPtr);
int main(void){
int numPets;
puts("How
many pets do you have?");
scanf("%i",&numPets);
if (numPets > 0){ // not required to capture this, but why
bother if no pets
struct Pets petArray[numPets];
int count;
for (count = 0; count < numPets;
count++){
puts("please enter the pet name, type and age");
scanf("%s%s%i", petArray[count].name,
petArray[count].type,
&(petArray[count].age));
}
struct Pets bestPet;
findBestPet(petArray, numPets, &bestPet);
printf("The
best pet is %s who is a %s and is %i years
old\n",
bestPet.name, bestPet.type, bestPet.age);
// the printing
of the array is not required but helpful for testing
for (count = 0; count < numPets;
count++){
printf("Pet
#%i is %s who is a %s and is %i
years old\n",
count, petArray[count].name, petArray[count].type,
(petArray[count].age));
}
}
}
// sadly, in
class I used this as an example to insist you follow my
// instructions in the design of the function
header exactly, but
// in this function header, you had to also
include the arrayLength because
// passed arrays do not know their length. This
is something I would
// have wanted you to question me about on the
test so I could clarify
void findBestPet( struct Pets petArray[], int arrayLength, struct Pets * bestPet){
int count;
if (arrayLength == 0) { return; }
*bestPet
= petArray[0];
// seed with the first pet
for
(count = 1; count < arrayLength; count++){
if (petArray[count].age > bestPet->age) {
*bestPet = petArray[count];
}
}
}
8. Comparison:
· Which paradigms do C, Java and Prolog each represent?
C - Imperative Procedural
Java - Imperative Object Oriented
Prolog - Declarative Logic
· How does C handle memory differently than Java?
Java has its own garbage collection and does not
expose the memory addresses as much as C
· How is a class in Java different from a structure in C?
A class in
java has methods and properties, but a structure in c just has properties
Prolog
Programming Exercises:
P1. Write 2 prolog facts:
· One fact to represent mr jones lives in a green house with a cat
lives(jones, green, cat).
Or lives("mr
jones" , green, cat).
· Another fact to represent that mr bozo lives in a yellow house with a dog.
lives(bozo, yellow, dog).
P2. Given these facts, write the requested rules:
female(amy).
female(mary).
female(lucy).
female(sally).
male(tim).
male(jim).
male(frank).
parent(jim,mary).
parent(jim,amy).
parent(lucy,mary).
parent(sally,amy).
parent(sally,frank).
Note that the parent rule is meant to read the first parm is a parent of the second parm, so jim is a parent of mary.
Write a rule for sibling(Sib1,Sib2) to be true when a male or female has the same parent.
sibling(Sib1,Sib2):-parent(X,Sib1),parent(X,Sib2).
Write a rule for daughter(Parent,Child) to be true when the child is a female.
daughter(Parent,Child):- parent(X,Child),female(Child).
Write a rule for mother(X) to be true only when the mother is both a parent and female.
mother(X):- parent(X,Child), female(X).
P3. Write a prolog query given facts and rules.
Given this Knowledgebase
point(a,2,3).
point(b,1,3).
point(c,5,3).
point(d,4,2).
point(e,7,3).
point(f,2,9).
point(g,5,9).
point(h,4,8).
point(i,9,2).
point(j,9,8).
magicLetterPoints(A,B,C,D):-
point(A,Ax,Ay),
point(B,Bx,By),
point(C,Cx,Cy),
point(D,Dx,Dy),
Ay = By,
Ax = Cx,
Ay < Cy,
Ax < Bx,
Dy = Cy,
Bx = Dx.
Write a query that will print all the magicLetterPoints that are found in the knowledgebase.
magicLetterPoints(First,
Second, Third, Fourth). (and then hit ; after each
answer.)
What letter does it create?
Z
How many answers are there to this query in the given knowledgebase?
2
First = a,
Second = c,
Third = f,
Fourth = g ;
First = d,
Second = i,
Third = h,
Fourth = j ;
false.