what do the following printf statements output?
printf("%1d\n%2d\n%3d\n", 24, 24, 24);
printf("%.2lf\n%4.1lf\n%6.4lf\n", 1.6666, 1.6666, 1.6666);
if you put a 1 right after the % in a format specifier, you're telling
printf that you want the minimum width to be 1 character. in our case,
the %1d is used to print 24, which is represented with
two characters on the screen ['2' and '4']. since 24 is printed with
two characters, and we told printf that the minimum width is 1
character, nothing interesting happens for this example, since we are
printing two characters, and our format specifier indicates that we
want the minimum width to be 1 character [and 2 is bigger than 1]. so
the first line of output will be:
24
let's look at the second format specifier. we said
%2d. this tells printf that we want the minimum width to
be 2 characters. we're printing 24 again, which is printed with two
characters, so nothing interesting happens, because we are printing
two characters, and our minimum width is 2 [and 2 is equal to 2]. the
second line of output is:
24
let's look at the third format specifier. something interesting
happens this time, i promise. we said %3d. we're printing
24 again, which is still 2 characters, but our format specifier
indicates that we want at least 3 characters of output. in these
situations, printf will add spaces in front of the output to reach the
minimum width. in our case, one space will be added, because we need
one more character to reach the minimum width [2+1 = 3]. so, the third
line of output is:
24
let's look at the second printf statement. when you put a decimal
point and a number after the %, it tells the computer how many digits
after the decimal point you want to see. since we said
%.2lf, we're saying that we want two digits after the
decimal point. so the first line of output for this printf statement
will be:
1.67
note that printf rounds. if i said printf("%.2lf\n",
1.543), the output would be 1.54.
let's look at the next format specifier. we ask for
%4.1lf, which means we want the minimum width to be 4,
and we want 1 digit after the decimal point. so the output is:
1.7
one space is added, because it takes 3 characters to print 1.7.
the final format specifier is %6.4lf. this says we want
the minimum width to be 6 characters, and we want 4 digits after the
decimal point. the output is:
1.6666
no spaces are added, because it takes 6 characters to print 1.6666
so, to summarize, the complete output is:
24 24 24 1.67 1.7 1.6666
what is the output of this program?
#include <stdio.h>
void main()
{
int i;
for(i=3; i < 10; i++)
{
printf("%d\n", i);
if(i > 4)
{
printf("break\n");
break;
}
}
while(i > 2)
{
printf("%d\n", i);
i--;
}
printf("done\n%d\n", i);
}
let's trace through this program. the for loop says that
i starts at 3. 3 is less than 10, so we go into the body
of the loop. we print out 3, then we check if 3 is greater than
4. it's not, so we increase i by one [it's now 4], and we go into the
body again, since 4 is less than 10. we print out 4. now we check if 4
is greater than 4. it's not, so we increase i by one [it's now 5], and
we go into the body again, since 5 is less than 10. we print out 5,
and check if 5 is bigger than 4. it is, so we print out "break", then
we break.
the break takes us to the while loop. we check if i is greater than 2 [it is, i is currently 5], so we go into the body of the while loop, where we print out 5, then decrease i by one [so i is now 4]. we check if 4 is greater than 2 [it is], so we go into the body again, where we print out 4, and decrease i by one again [so i is now 3]. 3 is still greater than 2, so we go into the body again, print out 3, and decrease the value of i by one [so it's now 2]. 2 is not greater than 2, so we print out "done", followed by the final value of i [2], and we're done.
so, the output of this program is:
3 4 5 break 5 4 3 done 2
this program accepts three integers as input. describe the output of this program in one sentence [in other words, this program does something meaningful. what does this program do?].
#include <stdio.h>
int max(int a, int b);
void main()
{
int a,b,c;
scanf("%d %d %d", &a, &b, &c);
printf("%d\n", max(a, max(b, c)));
}
int max(int a, int b)
{
if(a > b)
return a;
else
return b;
}
let's take a look at the definition of max first. from
looking at the first line of the function definition, it accepts two
integers [a and b] as input, and outputs an integer. the body of the
function indicates that it returns a if a is bigger than b, and
returns b otherwise.
so if we think about this a bit more, it looks like the
max function takes two integers, and returns us the
larger one.
now let's take a look at main. it reads three integers from the keyboard, a, b, and c, and prints out max(a,max(b,c)). let's see what this does, working inside to outside. max(b,c) will return the larger of b and c. the output of max(b,c) becomes one of the inputs of the other call to max, so max(a,max(b,c)) will return the larger of a and (the larger of b and c).
if we think about this a little more, main will print out the largest of the three integers we input.
what is the output of this program?
#include <stdio.h>
int* vooble(int* a, int* b);
void main()
{
int a,b;
int* c;
a=5;
b=7;
c = vooble(&a, &b);
printf("%d %d %d\n", a, b, *c);
}
int* vooble(int* a, int* b)
{
int* c;
c = b;
b = a;
a = c;
*a = *a + 5;
*b = *a + *b;
printf("%d %d %d\n", *a, *b, *c);
return c;
printf("vooble\n");
}
sorry, but i don't have time to draw pictures this time. i'll try to explain in words.
in main's scope, there are two integer variables, a and b, in addition to a pointer to an integer called c. a initially contains the number 5, and b contains the number 7. we don't know what c contains until we do the function call to vooble.
when we call vooble, we pass it the addresses of a and b as input. this means that the pointer called a in vooble's scope points to the a in main's scope, and the b in vooble's scope points to the b in main's scope.
in vooble, we see that we need an additional pointer to an integer called c. after that, we have three assignment statements. we see that the value of c becomes the same as the value of b. since both c and b are pointers, this means that c points to the same thing that b points to.
the next line says that b points to the same thing that a points to, and the line after that says that a points to the same thing that c points to. after we do these three assignment statements, we see that a and c point at the variable called b in main, and b points to the variable called a in main.
next, we have two more assignment statements. the first says that the variable pointed at by a must be increased by 5. since a points at b in main, and the b in main contains the value 7, the b in main now contains the value 12.
the next line says that the variable pointed at by b must be increased by *a. *a means that we need to look at the value of the variable pointed to by a, which is 12. so we need to increase the value of the variable pointed at by b by 12. since b points at the a in main, which is 5, the a in main now has value 17.
next we print out the values of *a, *b, and *c. we know that a points
at b in main, b points at a in main, and c points at b in main, so we
see 12 17 12.
finally, we return c. this means that the c in main will have the same
value as the c in vooble, because we said c=vooble(&a,&b)
back in main. since both c's are pointers, this means that the c in
main will point to the same thing that the c in vooble points to. the
c in vooble points at the b in main, so the c in main also points at
the b in main.
we do not see "vooble" anywhere in the output,
because that printf statement is after the return.
back in main, we print out the values of a, b, and *c. a and b are 17
and 12, and c points at b, so we see 17 12 12.
to summarize, the output is:
12 17 12 17 12 12
what is the output of this program given this input? 2 5 3 4 1
#include <stdio.h>
int isgood(int x);
void main()
{
int a[5], i;
for(i=0; i < 5; i++)
scanf("%d", &(a[i]));
for(i=0; i < 5; i++)
if(isgood(a[i]))
printf("%d %d\n", i, a[i]);
}
int isgood(int i)
{
if(i % 2 == 0)
return 1;
else
return 0;
}
let's start with the isgood function. it accepts an
integer i as input, and returns an integer. the if
statement checks if the remainder of i divided by 2 is
equal to zero. in other words, it's checking if i is
even. if i is even, the function returns 1, otherwise, it
returns 0. don't forget that 0 is considered false, and everything
else is considered true.
now let's look at main. first we create an array of 5 integers called a, and then we create a single integer called i. the first for loop reads integers from the keyboard, and puts them into the array at positions 0,1,2,3,4. in other words, the first for loop fills the array with the numbers 2,5,3,4,1.
the next loop runs the isgood function on the numbers in the array at positions 0,1,2,3,4, and if the function returns true, it prints out the index number, and the contents of the array at that index number. so the output is:
0 2 3 4
the following program is supposed to accept five integers as input, and output the largest integer. complete the program.
#include <stdio.h>
#define SIZE 5
int max(int[]);
void main()
{
int a[SIZE];
int i;
for(i=0; i < SIZE; i++)
{
scanf("%d", &(a[i]));
}
printf("%d\n", max(a));
}
int max(int a[])
{
/* fill this in */
}
from looking at the framework provided, we know that the input to the max function is an array that contains 5 integers read from the keyboard. the output of the max function is sent to the screen by printf, so the max function needs to output the largest number in the array if this program is going to work.
how do we find the largest number in an array? one idea is to keep track of the biggest number we have seen so far, and to compare each number in the array to the biggest we've seen so far. if the number we're looking at is bigger than the biggest one we've seen so far, that number becomes the new biggest. here's what the code looks like:
int max(int a[])
{
int i;
int biggest=a[0];
for(i=0; i < 5; i++)
if(a[i] > biggest)
biggest = a[i];
return biggest;
}
draw a schematic diagram of memory after each statement executes. label the figure with variable names and contents of locations. if the value is unknown, use ? as the contents of that location. clearly show the number of bytes you are allocating.
int n=3; int* p1,p2; double* q1,q2; p1 = (int*) malloc(n * sizeof(int)); p2 = &(p1[n-1]); *p1 = 5; p1[n-1] = 3; q2 = (double*) malloc(n * sizeof(double)); q1 = &(q2[0]); *q1 = 5.5; q1[n-1] = *q2;
here's some useful information.
all pointers are 4 bytes [regardless of what type they point to] char is 1 byte int is 4 bytes float is 4 bytes double is 8 bytes
the above is almost always true. if you assume the above for the final, you'll be okay.
so how big is everything we create up above? n is an integer, so it's
4 bytes. p1, p2, q1, and q2 are all pointers so they are all 4
bytes. the first malloc asks for n * sizeof(int) bytes,
so malloc will return us a 12-byte piece of memory [3 * 4]. the second
malloc asks for n * sizeof(double) bytes, so malloc will
return us a 24-byte piece of memory [3 * 8].
so where do the pointers point to? we know that p1 points to the beginning of the piece of memory that malloc returns. this means that we can use p1 as an array of 3 integers, since it points to the beginning of a piece of memory big enough to hold 3 integers. the next line makes p2 point to the last cell in the array.
when we say *p1=5, we are putting a 5 into the piece of
memory pointed to by p1. since p1 points to the beginning of the 3
cells, we put the 5 into the first cell.
in general, if p1 is the name of an array, *p1 is the same thing as p1[0].
p1[n-1]=3 puts a 3 into the last cell of the array.
the next line allocates an array of 3 doubles, and q2 points to the beginning of the array. the next line makes q1 point to the same place that q2 points to.
in general, if q2 is the name of an array, q2 is the same thing as &(q2[0]).
the next line puts 5.5 into the first cell in the array, and the next line says that we want the value in the last cell of the array to be the same as the value in the first cell of the array.
suppose the file "input.txt" contains the text hello my name is
jeremy.
what is the output of the following program, and what is in the file "output.txt" after the program is run?
#include <stdio.h>
#include <string.h>
void main()
{
FILE* in;
FILE* out;
char buf[256];
int n;
int total=0;
in = fopen("input.txt", "r");
out = fopen("output.txt", "w");
while(1)
{
fscanf(in, "%s", buf);
if(feof(in))
break;
n = strlen(buf);
total = total + n;
fprintf(out, "%d\n", n);
}
printf("%d\n", total);
}
let's see what this program does. it starts by creating a bunch of variables, including a file pointer called in that points to the beginning of the file called input.txt, and a file pointer called out that points to the beginning of the file called output.txt.
next, we go into an infinite loop [it's okay, because the break statement lets us escape]. each time we go through the loop, we grab a word from input.txt, determine the number of characters in the word, add the number of characters in the word to our total, and write the number of characters in the word to output.txt.
if we go past the end of the file while reading input.txt, we break out of the loop, and print the total number of characters to the screen.
so, when we run this program, we expect output.txt to contain:
5 2 4 2 6
because those are the numbers of letters in each word of input.txt.
we expect to see 19 on the screen, because that is the
total number of characters in all the words.
the following program accepts an integer n as input, followed by n
more integers. the program outputs the n integers in reverse
order. for example, given the input 3 4 5 6, the program
will output 6 5 4. n is the first integer, so in this
example, n is 3. since n is 3, we receive 3 more integers as input,
and we output those 3 integers in reverse order.
the program only works if n is less than 5. modify the program so that it works for any n.
#include <stdio.h>
#define SIZE 5
void main()
{
int i;
int n;
int a[SIZE];
scanf("%d", &n);
for(i=0; i < n; i++)
{
scanf("%d", &(a[i]));
}
for(i=n-1; i >= 0; i--)
{
printf("%d\n", a[i]);
}
}
to make this program work for any n, we need to replace the fixed-size array with a dynamically allocated one. the code looks like this:
#include <stdio.h>
void main()
{
int i;
int n;
int* a;
scanf("%d", &n);
a = (int*) malloc(n * sizeof(int));
for(i=0; i < n; i++)
{
scanf("%d", &(a[i]));
}
for(i=n-1; i >= 0; i--)
{
printf("%d\n", a[i]);
}
free(a);
}
so now we say that a is a pointer to a piece of memory returned by malloc. we ask malloc for enough space to hold n integers. after doing the malloc, we can use a just like any other array of integers, because the name of an array is just a pointer to the beginning of the array, and a points to a piece of memory big enough to hold n integers, so we can use a as an array.
since we can use a as an array, the two for loops are unchanged.
at the end, we free a, to tell the computer that we don't need the piece of memory that malloc found for us anymore.