Question: Purpose: To go over: The bitwise ops of C Pointers and strings in C Assignment Bitwise operations Finish the Program! You may only use the
Purpose:
To go over:
The bitwise ops of C
Pointers and strings in C
Assignment
Bitwise operations
Finish the Program!
You may only use the integer constants given at the beginning. (You may use whatever integers you wish in string constants as long as they are for printf()'s. For example the format string "0x%08X" is useful for printing hexadecimal integers.)
You may only use the following integer operators:
+
-
++
--
<<
>>
~
|
&
<
>
=
!=
==
Sample output (32 bit):
$ ./funWithBits
Please enter a hexadecimal int (without the leading "0x"): DEADBEEF
11011101111010101111011101111101 0xDDEAF77D
Please enter a hexadecimal int (without the leading "0x"): 12345678
01000001001000110001111001101010 0x41231E6A
Please enter a hexadecimal int (without the leading "0x"): 12344444
01000001001000110010001000100010 0x41232222
Please enter a hexadecimal int (without the leading "0x"): FFFFFFFF
11111111111111111111111111111111 0xFFFFFFFF
Please enter a hexadecimal int (without the leading "0x"): 0
/*-------------------------------------------------------------------------*
*--- ---*
*--- funWithBits.c ---*
*--- ---*
*--- This program demonstrates the functionality of the bitwise ---*
*--- integer operations in C. ---*
*--- ---*
*--- ---- ---- ---- ---- ---- ---- ---- ---- ---*
*--- ---*
*--- Version 3b 2018 June 20 Joseph Phillips ---*
*--- ---*
*-------------------------------------------------------------------------*/
#include
#include
#include
typedef unsigned int ourInt_t;
#define OUR_INT_INPUT_FORMAT "%X"
#define OUR_INT_OUTPUT_FORMAT "0x%08X"
#define OUR_INT_DECIMAL_OUTPUT_FORMAT "%10u"
// PURPOSE: To give the integer constants to use.
//
// USE THESE CONSTANTS ONLY!
//
const char ZERO = 0;
const char ONE = 1;
#define TWO 2
const char NIBBLE_WITH_ALL_BITS_ON
= 0xF;
const ourInt_t BYTE_WITH_ALL_BITS_ON
= 0xFF;
const ourInt_t NUM_BITS_PER_NIBBLE
= 4;
const ourInt_t NUM_BITS_PER_BYTE
= 8;
const ourInt_t NUM_NIBBLES_PER_BYTE
= TWO;
const ourInt_t NUM_BYTES_PER_WORD
= sizeof(ourInt_t);
#define NUM_NIBBLES_PER_WORD \
(NUM_BYTES_PER_WORD * NUM_NIBBLES_PER_BYTE)
#define NUM_BITS_PER_WORD \
(NUM_BYTES_PER_WORD * NUM_BITS_PER_BYTE)
#define NUM_BITS_PER_WORD_MINUS_ONE \
(NUM_BITS_PER_WORD - ONE)
#define NUM_BITS_PER_BYTE_PAIR \
(NUM_BITS_PER_BYTE * 2)
const int TEXT_LEN = 64;
// PURPOSE: To print 'u' both in binary and in hexadecimal, followed by a
// newline character. No return value.
void printBinaryAndHex
(ourInt_t u
)
{
ourInt_t place;
printf(" ");
// HINT: (binary)
// Make an integer with its highest bit on. Compare it with 'u'.
// If the corresponding bit is on in 'u' then print '1', else print '0'.
// Now move the bit over to the next lower bit position.
// HINT: (hexadecimal)
// Use format OUR_INT_OUTPUT_FORMAT.
for (place = (ourInt_t)ONE << (NUM_BITS_PER_WORD - ONE);
place != ZERO;
place = place >> ONE
)
{
if ( (place & u) == place )
printf("1");
else
printf("0");
}
printf("\t" OUR_INT_OUTPUT_FORMAT " ",u);
}
// PURPOSE: To ask for and get a hexadecimal integer. Keeps asking until
// gets legal hexadecimal integer. Returns the integer. No parameters.
ourInt_t getHexadecimalInt ()
{
char text[TEXT_LEN];
ourInt_t u;
ourInt_t numRead;
do
{
printf(" Please enter a hexadecimal int (without the leading \"0x\"): ");
fgets(text,TEXT_LEN,stdin);
numRead = sscanf(text,OUR_INT_INPUT_FORMAT,&u);
}
while (numRead < ONE);
return(u);
}
// PURPOSE: To return a value such that:
// * The lowest half of the bytes are all 0
// * The highest half of the bytes are the highest half of the bytes of 'u'
// that have been rolled to the right by one nibble.
// Thus, if 'ourInt_t' is 'unsigned int' (size = 4 bytes) then:
// rollHiBytesRightOneNibble(0xDEADBEEF) = 0xDDEA0000
// rollHiBytesRightOneNibble(0x12345678) = 0x41230000
// rollHiBytesRightOneNibble(0xFFFFFFFF) = 0xFFFF0000
// rollHiBytesRightOneNibble(0x12344444) = 0x41230000
ourInt_t rollHiBytesRightOneNibble
(ourInt_t u
)
{
// I. Application validity check:
// II.A. Make mask with value 0xFFFF0000:
int i;
ourInt_t mask = ZERO;
// HINT:
// (1) In a loop that goes over half of the bytes of NUM_BYTES_PER_WORD do
// (a) Incorporate another byte-full of 1s into 'mask',
// (b) then shift 'mask' by one byte
// This will make 0x0000FFFF
// (2) Shift 'mask' the appropriate amount to make 0xFFFF0000
// YOUR CODE HERE
// II.B. Do roll:
//
// YOUR CODE HERE
// III. Return value:
return( 0x0 );
}
// PURPOSE: To return a value such that:
// * The highest half of the bytes are all 0
// * The lowest half of the bytes are the lowest half of the bytes of 'u'
// with there bit order reversed.
// Thus, if 'ourInt_t' is 'unsigned int' (size = 4 bytes) then:
// reverseBitsOfLoBytes(0xDEADBEEF) = 0x0000F77D
// reverseBitsOfLoBytes(0x12345678) = 0x00001E6A
// reverseBitsOfLoBytes(0xFFFFFFFF) = 0x0000FFFF
// reverseBitsOfLoBytes(0x12344444) = 0x00002222
ourInt_t reverseBitsOfLoBytes
(ourInt_t u
)
{
// I. Application validity check:
// II. Compose value:
// YOUR CODE HERE
// III. Finished:
return(0x0);
}
// PURPOSE: In a loop to ask for a hexadecimal integer (use
// getHexadecimalInt()) and quit the loop if they enter 0. If they
// enter non-zero to:
// (1) Roll the half most significant bytes of the integer right by 4
// (keeping the result in those half most significant bytes)
// (2) Reverse order of the bits in the half least significant bytes
// (keeping the result in those half most least bytes).
void rollHiBytesRightOneNibble_reverseBitsOfLoBytes
()
{
// I. Application validity check:
// II. Do work:
ourInt_t u;
while ( (u = getHexadecimalInt()) != 0 )
{
printBinaryAndHex(rollHiBytesRightOneNibble(u) | reverseBitsOfLoBytes(u));
}
// III. Finished:
}
// PURPOSE: To harass Computer System II students into learning bit-wise
// integer manipulations. Ignores parameters. Return 'EXIT_SUCCESS' to
// OS.
int main ()
{
rollHiBytesRightOneNibble_reverseBitsOfLoBytes();
return(EXIT_SUCCESS);
}
Strings
Finish this program that:
Asks the user to enter an integer (1-20)
Gets that number of strings from the user (array0)
Again, gets that number of strings from the user (array1)
Compares the two arrays. To be equal:
array0 must have the same strings as array1, but in reverse order (That is, the string in array0[0] must match the string in array1[numWords-1], array0[1] must match the string in array1[numWords-2], etc)
The case of the strings does not matter.
free()s the arrays, and the contents in the arrays.
Example:
$ ./assign2
Please enter the number of words (1-20): hello
Please enter the number of words (1-20): 0
Please enter the number of words (1-20): 21
Please enter the number of words (1-20): 3
Word 0: Joe
Word 1: likes
Word 2: chocolate
Word 0: CHOCOLATE
Word 1: likes
Word 2: JOE
The two arrays are equal.
$ ./assign2
Please enter the number of words (1-20): 3
Word 0: Joe
Word 1: likes
Word 2: chocolate
Word 0: Joe
Word 1: likes
Word 2: chocolate
The two arrays are NOT equal.
/*-------------------------------------------------------------------------*
*--- ---*
*--- funkyStringComp.c ---*
*--- ---*
*--- This file defines a C program that enters to arrays of ---*
*--- C-strings and tells if they are equivalent when the array ---*
*--- orderings are reversed. The case of the letters is ignored. ---*
*--- ---*
*--- ---- ---- ---- ---- ---- ---- ---- ---- ---*
*--- ---*
*--- Version 1a 2018 June 20 Joseph Phillips ---*
*--- ---*
*-------------------------------------------------------------------------*/
#include
#include
#include
#define TEXT_LEN 256
// PURPOSE: To repeatedly ask "Please enter the number of words (1-20): ",
// get text, and convert it to an integer. If the integer is between
// 1 and 20, it is returned. Otherwise the question is asked again.
int getNumWords ()
{
char text[TEXT_LEN];
int number;
// YOUR CODE HERE
}
// PURPOSE: To have ask the user for 'arrayLen' words, and to have 'array'
// point to heap-allocated copies of them. This function assumes that the
// memory for 'array' has already been allocated, BUT the memory for the
// individual strings must still be allocated. No return value.
void fillWordArray (char** array,
int arrayLen
)
{
int i;
char text[TEXT_LEN];
// YOUR CODE HERE
}
// PURPOSE: To return 1 if:
// word in 'array0[0]' is equivalent to the word in 'array1[arrayLen-1]',
// word in 'array0[1]' is equivalent to the word in 'array1[arrayLen-2]',
// etc., where the case of the letters is ignored.
// Returns 0 otherwise.
//
// HINT: Change all chars to uppercase with toupper(*cPtr)
int areEqual(char*const* array0,
char*const* array1,
int arrayLen
)
{
int wordInd;
int charInd;
const char* word0;
const char* word1;
// YOUR CODE HERE
}
// PURPOSE: To do 'free()' on all 'arrayLen' elements of 'array', and then
// to 'free(array)' itself. No return value.
void freeArray (char** array,
int arrayLen
)
{
int i;
// YOUR CODE HERE
}
int main ()
{
int numWords = getNumWords();
char** array0 = (char**)calloc(numWords,sizeof(char*));
char** array1 = (char**)calloc(numWords,sizeof(char*));
fillWordArray(array0,numWords);
fillWordArray(array1,numWords);
if ( areEqual(array0,array1,numWords) )
{
printf("The two arrays are equal. ");
}
else
{
printf("The two arrays are NOT equal. ");
}
freeArray(array1,numWords);
freeArray(array0,numWords);
return(EXIT_SUCCESS);
}
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
