Several misc. C questions
I'm teaching myself C at the moment, and I want to ask a few questions that are puzzling me at the moment.
First, I'm working with bitwise operators at the moment, trying to familiarize myself with their use. I understand WHAT all the different operators I've been exposed to( & , |, ^, ~, and <</>>) are supposed to do, but some of the exact details are a bit fuzzy.
I was looking at the solution posted to problem 2-7 in K&R:
Quote:
Write a function invert(x,p,n) that returns x with the n bits that begin at position p inverted (i.e., 1 changed into 0 and vice versa), leaving the others unchanged.
The page I browed had this solution:
Code:
unsigned invert(unsigned x, int p, int n)
{
return x ^ (~(~0U << n) << p);
}
/* main driver added, in a hurry while tired, by RJH. Better test driver suggestions are welcomed! */
#include <stdio.h>
int main(void)
{
unsigned x;
int p, n;
for(x = 0; x < 700; x += 49)
for(n = 1; n < 8; n++)
for(p = 1; p < 8; p++)
printf("%u, %d, %d: %u\n", x, n, p, invert(x, n, p));
return 0;
}
I noticed a couple bugs in the code, so I modified it a bit, including renaming all the variables, because, while brevity is great, I WILL get mixed up while reading code if the variable names aren't clear:
Code:
#include <stdio.h>
/* Modified version of solution to exercise 2-7. Original by RJH. */
unsigned int flipbits(unsigned int opvar, int flipnum, int flipadr)
{
return opvar ^ (~(~0U << flipnum) << (flipadr-flipnum));
}
int main(void)
{
unsigned int opvar;
int flipnum, flipadr;
for(opvar = 0; opvar < 700; opvar += 49)
for(flipnum = 1; flipnum < 8; flipnum++)
for(flipadr = flipnum; flipadr <= 8; flipadr++)
printf("%u, %d, %d: %u\n", opvar, flipnum, flipadr, flipbits(opvar, flipnum, flipadr));
return 0;
}
My understanding in making the modifications is that the offset should not be exceeded by the number of bits to be flipped, and that the mask created by(in the original code) would end up placed by the original code so that its leftmost bit was at bit n+p+1, whereas it should be placed at p+1.
Is this a correct assessment?
Also, I want to make sure I understand exactly what this(updated) code is doing:
1. Generate a single bit 0 with 0U, then reverse it to single bit 1U
2. Move 1U flipnum places to the left, resulting in(where flipnum == 5) 100000
3. Reverse 100000 to 011111
4. Move 011111 (where offset == 7) an additional 2 places left, to make 01111100
5. Apply this mask to opvar, flipping all bits that line up with the 1s, then return this numeric value as an int.
I was considering that in the main function, could not
Code:
for(flipnum = 1; flipnum < 8; flipnum++)
for(flipadr = flipnum; flipadr <= 8; flipadr++)
be replaced with
Code:
for(flipnum = 1; flipnum < sizeof(int); flipnum++)
for(flipadr = flipnum; flipadr <= sizeof(int); flipadr++)
to more strenuously test the function? I mean, not that it really *needs* the testing, but just in theory. Also, if you were using more dynamic values, I'd think that checking for flipnum > flipadr would be a good idea inside the function, since that could have unexpected results.
Also, a question about pointers:
I am guessing from what I've read that local variables aren't illegal to write to by other functions, just not visible. In other words, if function a() calls function b(), and passes a local variable address to it, that function b() would be able to alter the contents of that variable, since it now knows where it is.
EG., in scanf(), you pass it the address of some variable, it writes data to that address, then ends.
Is this a correct understanding, or am I completely off track?
Thanks for anyone's help in advance, hope I'm not being a nuisance.
Edit: Fixed some stupid typos.