Cycle through certain range in array in C - c

I have this code
int x = 0
int MAX = 21;
int MIN = 18;
char *arr[40];
do{
char* current = cycle(x,arr)
x++;
}while(x<10000000)
My cycle() currently cycles through entire array
unsigned char *cycle(int counter, unsigned char *packets[40]){
int tmp = counter % 40;
return packets[tmp];
}
But I want it to cycle in array just in [MIN,MAX] range.
So the return values in while loop are: arr[18], arr[19], arr[20], arr[21], arr[18], arr[19]...
Any idea how to implement this? I don't want solutions using global variable.
Thanks for help!

Try something like this:
sometype cycle_range(int counter, sometype array[], unsigned min, unsigned max) {
sometype* first = array+min;
unsigned length = max-min+1;
return first[counter % length];
}
This works just like your solution, but it starts min elements further in array and loops over max-min+1 elements instead of 40.
(sometype is unsigned char* in your case, but you can substitute another type here if you want)

unsigned char *cycle(int counter,int min, int max, unsigned char *packets[40]){
int tmp = (counter % (max - min + 1)) + min;
return packets[tmp];
}

Related

Ex. 2.1 K&R 2nd edition: How can I calculate the variables?

I am a beginner in programming. I referred to power function in chapter 1 and modified it to be power_sum function. My calculation is to insert value of bits in "show_val()" to show range of each variable. The problem is in the main when I want to insert a value into show_val. Please guide me how to solve this. Thank you.
#include <stdio.h>
int power_sum(int base, int n);
void show_val(int power);
int main() {
unsigned char vc = show_val(8);
/* I try to show range of unsigned char here, but because show_val
is a void function, so it becomes error.*/
}
/* power_sum: raise base to n-th power and sum up; n => 0 */
int power_sum(int base, int n) {
int i, p, sum;
p = 1;
sum = 0;
for (i = 1; i <= n; ++i) {
p = p * base;
sum = sum + p;
}
sum = sum - 2;
return sum;
}
/* show_val: to show value of each variable */
void show_val(int pw) {
int n;
int i;
n = power_sum(2, pw);
for (i = 0; i < 10; ++i) /* to display increments of a value ten times */ {
printf("%d\n", ++n);
}
}
You are trying to assign void function void show_val(int pw) (a function that returns nothing) to unsigned char vc variable. If you want to return value from show_val function change: int show_val(int pw) and return something.
Otherwise, if you don't want to return anything, you can just call function in main:
int main()
{
show_val(8);
}
unsigned char vc = show_val(8);
Let us break the above piece of code into LHS and RHS.
LHS :
Its a variable expecting a character to be inputed.
Now what is being done in RHS
RHS:
You have given show_val(8)
Which is a mistake
Why?
Because if you see you show_val declaration:
void show_val(int)
You are returning a void i.e nothing.
And trying to equate with char on LHS.
So, the compiler will definitely throw an error.
There are more changes to be made,
1st edit this part correctly in the question if you are clear and then we can look upon the other changes.

Finding frequency of an integer in an array and calculating x to the nth power

I am trying to solve two different C problems and would like some help and advice in order to better understand how C works and if I'm on the right track with these.
First problem is: To write a function that counts the number of times the value (x) appears among the first (n) elements of an array and returns that count as the frequency of x in theArray. So, an example would be if the array being passed contained the values {5, 7, 23, 8, 23, 67, 23}. And n was 7 and x was 23, then it would return a value of 3 since 23 occurs 3 times within the first 7 elements of the array.
Here is what I have so far:
#include <stdio.h>
#define SIZE 20 /* just for example - function should work with array of any size */
int frequency (int theArray[], int n, int x)
{
int i;
int count = 0;
for (i = 0; i < n; i++)
{
if (theArray[i] == x)
{
count = count++;
}
}
return (count);
}
int main(void)
{
/* hard code n and x just as examples */
int n = 12; /* look through first 12 items of array */
int x = 5; /* value to find */
int numberFrequency;
long int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
numberFrequency = frequency (theArray[SIZE], n, x);
printf ("%i", numberFrequency);
return 0;
}
Currently I'm getting a run time error message and believe it has something to do with the for loop function.
Second problem is: Write a function that raises an integer to a positive integer power. Have the function return a long int, which represents the results of calculating x to the nth power. Do not use the C pow library function and do not use recursion!
My code so far:
#include <stdio.h>
int x_to_the_n (int x, int n)
{
int i;
long int result = 1;
if (n == 0)
{
return(result);
}
else
{
for (i = 0; i < n ; ++i)
{
/* equation here - How can I make (x*x*x*x*x*x,etc...? */
result = x*(n*x);
}
}
return (result);
}
int main(void)
{
int x =4;
int n =5;
long int result;
result = x_to_the_n (x, n);
printf ("%i", result);
return 0;
}
I can't use recursion so that is out of the question. So, I thought the next best thing would be a for loop. But I'm a little stuck in how I would go about making a for loop do (xxx*x....) based on value of (n). Any help and advice would be appreciated!
In the first problem you give an element after the array as a parameter to your function.
You define a long int array, and pass it into a function expecting an int array.
long int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
should be
int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
Instead of this:
numberFrequency = frequency (theArray[SIZE], n, x);
try this:
numberFrequency = frequency (theArray, n, x);
And replace:
count = count++;
with:
count++;

Finding how to remove largest and second largest in array in c

The assignment is as followed and is coded in Keil which is an ide for c.
unsigned short data[100] = {
58473, 33594, 38638, 26741, 13018, 29262, 16377, 12354, 46079,
57240, 48949, 34054, 16212, 58485, 6198, 38678, 22525, 51012,
43489, 8861, 54291, 21524, 7166, 22698, 39899, 27113, 30443,
14888, 27935, 40035, 48710, 18067, 36008, 12644, 56319, 15852,
54685, 61789, 57030, 4763, 10655, 24656, 60363, 23712, 28474,
31274, 39647, 56166, 8219, 47413, 22201, 3129, 25630, 36027,
4499, 56525, 32743, 9380, 22102, 51009, 16309, 16589, 26322,
65279, 22780, 26002, 41101, 26082, 13389, 59504, 15784, 33416,
57970, 8519, 57819, 34406, 40864, 31575, 52154, 60214, 39910,
43107, 64825, 40284, 60148, 27287, 38245, 49930, 54062, 50668,
30553, 27904, 38960, 49407, 10508, 62147, 33019, 3047, 33750, 18024};
Write functions to preform the following operations on the array. You must pass the array to functions in order to receive full credit.
Find the index of the largest number, FindInexOfLargest().
Remove a specified entry, given an index, in the array, RemoveEntry(). Note that data appearing in the array after the removed entry is to be shifted to the left, so that data[i] becomes data[i+1].
Remove the largest entry in an array, RemoveLargestEntry(). The array is mutated to remove the largest entry. The value of the largest entry is returned by the function.
Remove the second largest entry in an array, RemoveSecondLargestEntry(). The function should return the numerical value of the second largest entry in an array, and remove that value.
The functions written for 3 and 4 should use the functions written in 1 and 2. For full credit, no loops should appear in the functions written in part 3 and 4.
This is my code that isn't working right and I can't find out where the mistake is. It's a logical error somewhere I just don't know where.
unsigned short int data[100] = {
58473, 33594, 38638, 26741, 13018, 29262, 16377, 12354, 46079,
57240, 48949, 34054, 16212, 58485, 6198, 38678, 22525, 51012,
43489, 8861, 54291, 21524, 7166, 22698, 39899, 27113, 30443,
14888, 27935, 40035, 48710, 18067, 36008, 12644, 56319, 15852,
54685, 61789, 57030, 4763, 10655, 24656, 60363, 23712, 28474,
31274, 39647, 56166, 8219, 47413, 22201, 3129, 25630, 36027,
4499, 56525, 32743, 9380, 22102, 51009, 16309, 16589, 26322,
65279, 22780, 26002, 41101, 26082, 13389, 59504, 15784, 33416,
57970, 8519, 57819, 34406, 40864, 31575, 52154, 60214, 39910,
43107, 64825, 40284, 60148, 27287, 38245, 49930, 54062, 50668,
30553, 27904, 38960, 49407, 10508, 62147, 33019, 3047, 33750, 18024};
// ***** 2. Global Declarations Section *****
// FUNCTION PROTOTYPES: Each subroutine defined
unsigned short int FindIndexOfLargest(unsigned short int class[], unsigned short int start, unsigned short int end);
unsigned short int RemoveEntry(unsigned short int class[], unsigned short int size, int position);
unsigned short int RemoveLargestEntry(unsigned short int class[], unsigned short int size);
unsigned short int RemoveSecondLargest(unsigned short int class[], unsigned short int start, unsigned short int end);
// ***** 3. Subroutines Section *****
int main (void) {
printf("Largest: %u\n", FindIndexOfLargest(data, 0, 100));
printf("Removing: %u\n", RemoveEntry(data, 100, 7));
printf("Removing Largest: %u\n", RemoveLargestEntry(data, 100));
printf("Removing Second Largest: %u\n", RemoveSecondLargest(data, 0, 100));
}
unsigned short int FindIndexOfLargest(unsigned short int class[],unsigned short int start, unsigned short int end){
unsigned short int largest,i;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(class[i] > largest){
largest = class[i]; // new maximum
}
}
return (class[i]);
}
unsigned short int RemoveEntry(unsigned short int class[], unsigned short int size, int position) {
unsigned short int c;
for (c = (position - 1) ; c < (size - 1) ; c++ ) {
class[c] = class[c+1];
}
return class[c];
}
unsigned short int RemoveLargestEntry(unsigned short int class[], unsigned short int size) {
return RemoveEntry(class, size, FindIndexOfLargest(class, 0, 100));
}
unsigned short int RemoveSecondLargest(unsigned short int class[], unsigned short int start, unsigned short int end) {
unsigned short int Largest = FindIndexOfLargest(class, start, end);
unsigned short int firstLarge = FindIndexOfLargest(class, start, (Largest-1));
unsigned short int secondLarge = FindIndexOfLargest(class, (Largest+1), end);
if (firstLarge > secondLarge) {
return RemoveEntry(class, end, firstLarge);
}
else {
return RemoveEntry(class, end, secondLarge);
}
}
There is one mistake in FindIndexOfLargest function Change it to:
unsigned short int FindIndexOfLargest(unsigned short int class[],unsigned short int start, unsigned short int end){
unsigned short int largest,i;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(class[i] > largest){
largest = class[i]; // new maximum
}
}
return (largest); //NOTE CHANGE HERE:Return largest number
}
As the function name suggest if you want to return the index of largest number then change it to:
unsigned short int FindIndexOfLargest(unsigned short int class[],unsigned short int start, unsigned short int end){
unsigned short int largest,i;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(class[i] > largest){
largest = i; // NOTE CHANGE HERE:new maximum index
}
}
return (largest); //NOTE CHANGE HERE:Return largest index
}
As pointed out by Vagish There is a mistake in the function FindIndexOfLargest you are doing this
unsigned short int FindIndexOfLargest(unsigned short int class[],unsigned short int start, unsigned short int end){
unsigned short int largest,i;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(class[i] > largest){
largest = class[i]; // new maximum
}
}
return (largest); // This is returning the largest no rather than returning the index
}
so do it like this
unsigned short int FindIndexOfLargest(unsigned short int class[],unsigned short int start, unsigned short int end){
unsigned short int largest,i,index;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(class[i] > largest){
largest = class[i]; // new maximum
index=i;
}
}
return (index); //This is returning the index of the largest
}
There is also the problem in the Remove Entry function do it like this
unsigned short int RemoveEntry(unsigned short int class[], unsigned short int size, int position) {
unsigned short int c;
for (c =position; c <size;++c ) {
class[c] = class[c+1];
}
size-=1;
return size; //Return size of new array after removing the data
}
Well then there remains the last function, please try to find the logical error there and if not able let us know :)
Hope these answer helps
unsigned short int FindIndexOfLargest(unsigned short int tempArr[],unsigned short int start, unsigned short int end){
unsigned short int largest,i;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(tempArr[i] > tempArr[largest]){
largest = i; // new maximum
}
}
return (largest); //Change return value class[i] to largest;
}
void RemoveEntry(unsigned short int class[], unsigned short int size, int position) {
unsigned short int c;
for (c = (position - 1) ; c < (size - 1) ; c++ ) {
class[c] = class[c+1];
}
//return class[c]; <<< array pass by pointer,so no need to return; *change unsigned short int to void.
void RemoveLargestEntry(unsigned short int tempArr[], unsigned short int size) {
RemoveEntry(class, size, FindIndexOfLargest(tempArr, 0, 100)); // This is the same with RemoveEntry function;
}
unsigned short int RemoveSecondLargest(unsigned short int tempArr[],unsigned short int start, unsigned short int end) {
unsigned short int Largest,PositionLargest,SecondLargest,PositionSecondLargest;
Largest = tempArr[FindIndexOfLargest(tempArr[],0,end)];
RemoveLargestEntry(tempArr,end); /*Remove largest and sencond largest number in the Array */
SecondLargest = FindIndexOfLargest(tempArr,0,end);
RemoveLargestEntry(tempArr,end-1);
tempArr[99] = Largest; // Add number at the end of the array;
return(SecondLargest);
}
Function 4 is only for your provide array. If the situation where the number in the array is less than 100(e.g 30),function 4 will be useless.

Finding the length of a dynamically allocated array of unsigned long long

I have an array of unsigned long long numbers. I initialize the first 12 elements. The array changes size throughout the programs runtime. How can I find out the length of the array.
I can't use sizeof(array)/sizeof(unsigned long long) since it doesn't work correctly in this case.
I tried using this loop:
count = 0;
while ( array[count] ) count++;
return count;
The problem with this method is that it still returns the wrong length.
Here is the basic rundown of the code.
unsigned long long *prime = (unsigned long long *)calloc(1000, sizeof(unsigned long long);
prime[0] = 3;
prime[1] = 5;
....
prime[11] = 41;
unsigned long long *ptrEmpty = &prime[12];
int sizeComp;
//User can change change the size of the array here to create a larger list of primes.//
for( i = 43, sizeComp = 12; sizeComp < length(prime); i += 2 ){
// Do stuff...
}
How can I find this length?
One way is to keep a counter every time an element is inserted into the array. Maybe you can encapsulate the array in a struct e.g:
typedef struct int_arr
{
int* arr_ptr;
size_t max_size;
int curr_elem;
} int_arr;
Then you can specify init, add and get_max_size and get_curr_size functions.
Init:
int_arr* arr_init(int_arr* ptr, size_t size)
{
ptr = calloc(size, sizeof(int);
ptr->max_size = size;
ptr->curr_elem = 0;
return ptr;
}
Add:
void add(int_arr* ptr, int value)
{
if (ptr->curr_elem < ptr->max_size)
ptr->arr_ptr[ptr->curr_elem++] = value;
else
printf("Max size reached!\n");
}
Get total size:
size_t get_total_size(int_arr* ptr) { return ptr->max_size; }
Get current size:
int get_curr_size(int_arr* ptr) { return ptr->curr_elem; }
Obviously replace int with your desired type.

Bitwise Operations C on long hex Linux

Briefly: Question is related to bitwise operations on hex - language C ; O.S: linux
I would simply like to do some bitwise operations on a "long" hex string.
I tried the following:
First try:
I cannot use the following because of overflow:
long t1 = 0xabefffcccaadddddffff;
and t2 = 0xdeeefffffccccaaadacd;
Second try: Does not work because abcdef are interpreted as string instead of hex
char* t1 = "abefffcccaadddddffff";
char* t2 = "deeefffffccccaaadacd";
int len = strlen(t1);
for (int i = 0; i < len; i++ )
{
char exor = *(t1 + i) ^ *(t2 + i);
printf("%x", exor);
}
Could someone please let me know how to do this? thx
Bitwise operations are usually very easily extended to larger numbers.
The best way to do this is to split them up into 4 or 8 byte sequences, and store them as an array of uints. In this case you need at least 80 bits for those particular strings.
For AND it is pretty simple, something like:
unsigned int A[3] = { 0xabef, 0xffcccaad, 0xddddffff };
unsigned int B[3] = { 0xdeee, 0xfffffccc, 0xcaaadacd };
unsigned int R[3] = { 0 };
for (int b = 0; b < 3; b++) {
R[b] = A[b] & B[b];
}
A more full example including scanning hex strings and printing them:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef unsigned int uint;
void long_Print(int size, const uint a[]) {
printf("0x");
for (int i = 0; i < size; i++) {
printf("%x", a[i]);
}
}
void long_AND(int size, const uint a[], const uint b[], uint r[]) {
for (int i = 0; i < size; i++) {
r[i] = a[i] & b[i];
}
}
// Reads a long hex string and fills an array. Returns the number of elements filled.
int long_Scan(int size, const char* str, uint r[]) {
int len = strlen(str);
int ri = size;
for (const char* here = &str[len]; here != str; here -= 8) {
if (here < str) {
char* tmp = (char*)malloc(4);
tmp[0] = '%';
tmp[1] = (char)(str - here + '0');
tmp[2] = 'x';
tmp[3] = '\0';
sscanf(str, tmp, &r[ri--]);
free(tmp);
break;
}
else {
sscanf(here, "%8x", &r[ri--]);
}
}
for (; ri >= 0; ri--) {
r[ri] == 0;
}
return size - ri;
}
int main(int argc, char* argv[])
{
uint A[3] = { 0 };
uint B[3] = { 0 };
uint R[3] = { 0 };
long_Scan(3, "abefffcccaadddddffff", A);
long_Scan(3, "deeefffffccccaaadacd", B);
long_Print(3, A);
puts("\nAND");
long_Print(3, B);
puts("\n=");
long_AND(3, A, B, R);
long_Print(3, R);
getchar();
return 0;
}
You'll certainly need to use a library that can handle arbitrarily long integers. Consider using libgmp: http://gmplib.org/
Before you can do any sort of bitwise operations, you need to be working with integers. "abeffccc" is not an integer. It is a string. You need to use something like strtol
to first convert the string to an integer.
If your values are too big to fit into a 64-bit long long int (0xFFFFFFFF,FFFFFFFF) then you'll need to use a Big Integer library, or something similar, to support arbitrarily large values. As H2CO3 mentioned, libgmp is an excellent choice for large numbers in C.
Instead of using unsigned long directly, you could try using an array of unsigned int. Each unsigned int holds 32 bits, or 8 hex digits. You would therefore have to chop-up your constant into chunks of 8 hex digits each:
unsigned int t1[3] = { 0xabef , 0xffcccaad , 0xddddffff };
Note that for sanity, you should store them in reverse order so that the first entry of t1 contains the lowest-order bits.

Resources