Why is the placement of variable declaration giving different results? - c

#include <stdio.h>
int order = 3;
int wt[10] = {2,1,3};
int price [10] = {100,50,150};
int maxW = 5;
void fracK() {
int curr_weight, i, max_i; // <<<<
float tot_price; // <<<<
int used[10]; // <<<<
//inititialising all used elements to 0
for (i = 0; i < order; ++i) {
used[i] = 0;
}
curr_weight = maxW;
while (curr_weight > 0) {
max_i = -1;
for (i = 0; i < order; ++i) {
if ((used[i] == 0) && ((max_i == -1) || ((float)price[i]/wt[i] > (float)price[max_i]/wt[max_i]))){
max_i = i;
}
}
used[max_i] = 1;
curr_weight -= wt[max_i];
tot_price += price[max_i];
if (curr_weight >= 0) {
continue;
}else {
tot_price -= price[max_i];
tot_price += (1 + (float)curr_weight/wt[max_i]) * price[max_i];
}
}
printf("%f", tot_price);
}
//driver function
int main(int argc, char *argv[]) {
fracK();
return 0;
}
in lines 9 to 11, if I declare float in the second or third line i.e. line 10 or 11, the final value returned is 197040072659526240000000000000000.000000, which is not my expected value.
However, when I declare the float variable in the first line, i.e. line 9, the final value returned is 250.000000 which is my expected value.

It should be:
float tot_price = 0;
then the placement probably will not matter. As is now, the code is adding numbers to uninitialized variable, which will not have predictable results.

Related

Why is this below code giving heap overflow Error by just changing the comparison operator from &&(AND) to ||(OR)?

I was trying to solve below problem:
Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must appear as many times as it shows in both arrays and you may return the result in any order.
Example 1:
Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2,2]
Here is my code:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
for(int i=0; i<nums1Size-1; i++){
if(nums1[i]>nums1[i+1]){
int temp = nums1[i];
nums1[i] = nums1[i+1];
nums1[i+1] = temp;
i = -1;
}
}
for(int i=0; i<nums2Size-1; i++){
if(nums2[i]>nums2[i+1]){
int temp = nums2[i];
nums2[i] = nums2[i+1];
nums2[i+1] = temp;
i = -1;
}
}
int i = 0;
int j = 0;
int* res = (int*)malloc(10* sizeof(int));
int k = 0;
if(!(nums1Size > nums2Size)){
int * temp = nums1;
nums1 = nums2;
nums2 = temp;
int tempint = nums1Size;
nums1Size = nums2Size;
nums2Size = tempint;
}
while(i<nums1Size && j<nums2Size){
if(nums1[i] > nums2[j]){
j++;
}
else if(nums1[i] < nums2[j]){
i++;
}
else{
res[k++] = nums1[i];
i++; j++;
}
}
*returnSize = sizeof(res)/sizeof(res[0]);
return res;
}
To simplify the problem you have to solve, let's first write a helper function that counts the number of occurrences of a particular element inside an array:
int count_elem(int* arr, int n, int elem) {
int count = 0;
for (int i = 0; i < n; i += 1) {
if (arr[i] == elem) {
count += 1;
}
}
return count;
}
Now, let's try to solve the problem following the problem description:
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
// here we allocate `res` with size of the biggest array, because that's the worst case we'll have
int* res = malloc(sizeof(int) * ((nums1Size > nums2Size) ? nums1Size : nums2Size));
// just to be sure `malloc()` did not return an error
if (res == NULL) {
return NULL;
}
// we'll keep track of how many elements we actually put inside `res`
*returnSize = 0;
// let's loop through all elements of `nums1`
for (int i = 0; i < nums1Size; i += 1) {
int elem = nums1[i];
// if we already put the element inside `res`, we skip this cycle
int count_res = count_elem(res, *returnSize, elem);
if (count_res > 0) {
continue;
}
// let's count the occurrences in both arrays
int count1 = count_elem(nums1, nums1Size, elem);
int count2 = count_elem(nums2, nums2Size, elem);
// let's calculate how many times the element must be present inside `res`
// i.e.: the same number of times of the array with the fewer occurrences of it
// NOTE: if `nums1` or `nums2` do not include the element, we also don't include it inside `res`
int count_min = (count1 < count2) ? count1 : count2;
// now let's put inside `res` as many times as we previously calculated
for (int i = 0; i < count_min; i += 1) {
res[*returnSize] = elem;
*returnSize += 1;
}
}
return res;
}
Let's try if it works:
int main(void) {
int arr1[] = {1, 2, 2, 1};
int arr2[] = {2, 2};
int res_size;
int* res = intersect(arr1, sizeof(arr1) / sizeof(arr1[0]), arr2, sizeof(arr2) / sizeof(arr2[0]), &res_size);
// let's print the result of `intersect()`
for (int i = 0; i < res_size; i += 1) {
printf("%d\n", res[i]);
}
return 0;
}
Output:
2
2
NOTE: the function is not optimized for speed nor for memory efficiency. This will be left as an exercise for the reader.
UPDATE
The previous version of the answer was wrong (sorry again). Now it should be correct.

Return multiple values from function prototype in C. Results are multiple products

So I have a function prototype find all products from two numbers whether it has 2 or 3 digits. I believe that function can only return one value. So how do I print out all possible values in main using printf statement?
int find_largest_products(int ndigits){
int min = 1;
int max;
int smallest_num;
int largest_num = 0;
int product = 0;
int max_min_product = 0;
//Finding the minima. 1 digit = 1; 2 digits = 10; 3 digits = 100
smallest_num = min * pow(10, ndigits-1);
//Finding the maxima. 1 digits = 9; 2 digits = 99; 3 digits = 999
for (int i = 0; i < ndigits; i++){
max = 9 * pow(10, i);
largest_num += max;
}
for (int x = largest_num; x >= smallest_num; x--){
for (int y = smallest_num; y <= largest_num; y++){
product = x * y;
max_min_product = product;
}
}
return max_min_product;
}
int main() {
int num = find_largest_palindrome(2);
printf("Results: %d\n", num);
return 0;
}
Callback function:
int find_largest_products(int ndigits, int (*callback)(int, void *), void *baton){
//...
//max_min_product = product;
int r= callback(product, baton);
if (r) return r;
//...
return 0;
}
int print_product(int product, void *ignored) {
printf(" %d", product);
return 0;
}
int main()
{
//...
printf("Results:");
find_largest_products(2, print_product, NULL); // Invocation is here
printf("\n");
//...
}
What about commas? What about newline every so many? We can adapt the callback.
int print_product(int product, void *baton) {
int *counter = baton;
if (counter % 8 == 7) {
printf(", %d\n", product);
else if (counter % 8 == 0)
printf("%d\n", product);
else
printf(", %d\n", product);
++*counter;
return 0;
}
But now the invocation should look like:
int counter = 0;
find_largest_products(2, print_product, &counter); // Invocation is here
Notice how this keeps state between invocations. Here it's an int, but it could easily be a struct or a pointer thereof to enable keeping arbitrary amounts of state.
So this is the pattern of a callback function that can do whatever it wants. The callback function takes the accumulating argument found by find_largest_products and the state argument baton from find_largest_products, and returns 0 to continue or nonzero to bail. Here the callback function only prints the value out and never fails. I also consider this lower-skill-level than dynamic memory. We only need to learn the somewhat annoying syntax for function pointers and the rest easy concepts. Note that we don't take the address of a function pointer with &; it's like an array in that regard.
To make the point this is the general form; here's the callback that could be passed to retrieve the list.
struct product_info {
int *products;
int nproducts;
int aproducts;
};
int gather_products(int product, void *baton)
{
struct product_info *info = baton;
// normal dynamic stretchy array zzzzz
if (info->nproducts == info->aproducts) {
if (info->aproducts == 0) {
info->products = malloc(sizeof(int)*4);
if (!info->products) return 1;
info->aproducts = 0;
} else {
void *more = realloc(sizeof(int) * (info->aproducts << 1));
if (!more) return 1;
info->aproducts <<= 1;
info->products = more;
}
}
// end stretchy array
info->products[info->nproducts++] = product;
return 0;
}
int main()
{
//...
printf("Results: ");
struct product_info info = { NULL, 0, 0 };
if (find_largest_products(2, gather_products, &info)) { // Invocation is here
fprintf(stderr, "Out of memory\n");
free(info->products);
}
for (int i = 0; i < info->nproducts; i++)
printf("%s%d", (i == 0) ? "" : ", ", info->products[i]);
free(info->products);
printf("\n");
//...
}
Returning the list requires dynamic memory. It's interesting to note that function pointers provides a separation of concerns that I've come to appreciate in these late days; we can separate the generating algorithm from the storing of the results.
Another sample: find biggest!
int biggest_product(int product, void *baton) {
int *biggest = baton;
if (*biggest < product) *biggest = product;
return 0;
}
int main()
{
int biggest = 0;
find_largest_products(2, biggest_product, &biggest); // Invocation is here
printf("Biggest product is: %d\n", biggest);
}
Notice how easy it is to swap what you do with the products as you generate them.

Dynamic Program in C

Hi Guys i have edited the questions.Here is my entire code.I have given basic amount of readability to my program.I hope u guys can understand the program.
#include<stdio.h>
#include<stdlib.h>
int Max_Min(int,int,int,int *, int *);
int *Max,Number;
int main()
{
int n1, n2,Maximum_Element=0,*Max;
int i = 0, j = 0;
scanf("%d",&Number);
Max =(int *) malloc(sizeof(int)*Number);//Array Max is created
for (int k = 0;k <(Number/2);k++)
{
scanf("%d", &n1);
scanf("%d", &n2);
Max[k] = Max_Min(0,1,0,&n1,&n2);//Passing integer elements n1,n2 with flag 0
}
Maximum_Element=Max_Min(1,1,((sizeof(Max)*Number)/8),Max,Min);//Passing array elements Max,Min with flag 1 to function Max_Min
printf("Maximum_Element=%d", Maximum_Element);
return 0;
}
int Max_Min(int flag,int Max_Min_flag,int length,int *n1,int *n2)//n1 and n2 should be able to handle array and integers
{
int i=0,j = 0,k1,k2,Min1 = 0, Min2 = 0,count=0, Not_Zero = 0,x=0,y=0, *New_Max = 0,*New_Min;
/*Recursive Loop for splitting the array elements and calling the array */
if (flag == 1)
{
New_Max = (int *)(malloc(sizeof(int)*length));
for (;i <= ((length) / 2);i = i + 2)//
{
k1 = n1[i];
j = i + 1;
if (j <= ((length + 1) / 2))
{
k2 = n1[j];
New_Max[count] = Max_Min(0, 1, 0, &k1, &k2);//It is passing integer elements with flag 0 to function Max_Min
count++;
}
}
New_Max[count] = n1[j + 1];
for (int i = 0;i < count + 1;i++)
{
**/* Problem is assigning Max[i]=New_Max[i] is not getting assigned*/**
Max[i] = New_Max[i];//Copying from New_Max to Max because New_Max will be overwritten,so possible chaunce of dataloss
Not_Zero++;
}
while ((sizeof(Max) / 4 - (Not_Zero))>0)
{
Max[Not_Zero] = 0;
Not_Zero++;
}
/*Logic for calling recursive functions based on the count*/
if (count > 1)
{
count--;
Max_Min(1, 1, count, Max, Min);//Calling Recursive function by Passing Entire Arrays with flag 1.
}
else if (count == 1 && Max[1] == 0)
{
*n1 = Max[0];
*n2 = Min[0];
}
else if (count == 1 && Max[2] == 0)
{
Max_Min(1, 1, count + 1, Max, Min);
count--;
}
}
/*Logic for Finding Maximum & Minimum element is present down*/
if (flag == 0)
{
printf("flag");
if (Max_Min_flag == 1)
{
if (*n1 > *n2)
{
}
else if ((*n1 < *n2) && Max_Min_flag == 1)
{
int temp = 0;
temp = *n1;//5
*n1 = *n2;//7
*n2 = temp;//5
}
}
else if (Max_Min_flag == 2)
{
if (*n1 > *n2)//7>2
{
int temp = 0;
temp = *n1;//2
*n1 = *n2;//2
*n2 = temp;//2,7
}
else if (*n1 < *n2)
{
}
}
}
return *n1;//7
}
Problem is assigning Max[i]=New_Max[i] in function Max_Min().It shows Run time error as "Access violation writing location 0x00000000."
First you need to #include <stdlib.h> to use malloc
You must declare your function before using it.
func must return int*.
Also in func "n", first "Max", and second "Max" needs to be the same variable. Rename "n" to "Max"
This is the code corrected with an extra printf;
#include <stdio.h>
#include <stdlib.h>
int *Max,Number=5;
int* func(int *Max)
{
for(int j=0;j<5;j++)
Max[j]=j;//Its not working in this line
return Max;
}
int main()
{
Max=(int *) malloc(sizeof(int)*Number);
for(int i=0;i<5;i++)
Max[i]=i;
int* x = func(Max);
for(int i=0;i<5;i++)
printf("%d", x[i]);
}
The following contains only minor adaptations of your code and it runs fine:
int *func(int *n);
int *Max,Number=5;
int main()
{
int *x,i;
Max=(int *) malloc(sizeof(int)*Number);
for(i=0;i<Number;i++)
Max[i]=i;
x=func(Max);
free(Max);
return(0);
}
int *func(int *n)
{
int j;
for (j=0;j<Number;j++)
n[j]=Number-j; // reverse the number, just to check
return Max;
}

C: Best way to index the digits in an integer

If I have an
int i = 11110001
How would I be able to convert this int into an int array where
int array[8] = {1, 1, 1, 1, 0, 0, 0, 1}
Using a little different approach and snprintf:
#include <stdio.h>
int main (void) {
int i = 11110001;
char arr[9]; //8 digits + \0
int array[8];
if ((snprintf(arr,9,"%d", i) == 8) { //return the 8 characters that were printed
int c;
for(c = 0; c < 8; c++)
array[c] = arr[c] - '0';
}
return 0;
}
P.S: I'm assuming positive values only
You may try like this:
#include <math.h>
char * convertNumber(unsigned int i) {
/* unsigned int length = (int)(log10((float)i)) + 1; */
/* char * arr = (char *) malloc(length * sizeof(char)), * x = arr; */
char * arr = malloc(8);
char * x = arr;
do
{
*x++ = i% 10;
i/= 10;
} while (i != 0);
return arr;
}
Try this :
#include<stdio.h>
void convert_int_to_array(unsigned int);
int main()
{
unsigned int a = 12345678;
convert_int_to_array(a);
return 0;
}
void convert_int_to_array(unsigned int a)
{
int array[25]; // array large enough for an integer
int i = 0, count = 0;
unsigned int num = a;
memset(array, '\0', 20); // I've not included the header file for this.
// gives a warning on compilation.
while(num > 0)
{
array[i] = num % 10;
num = num / 10;
++i;
++count;
}
for(i = count; i>=0;--i)
{
printf("array[%d] = %d\n",i, array[i]);
// or
printf("%d", array[i]);
// dont use both the printf statements, else you will see a
// messed up output.
}
}
BINARY REPRESENTATION :
#include<stdio.h>
struct bit
{
int a : 1;
};
int main()
{
struct bit b;
int d ,f,i;
d=f=256; // take any number of your choice
printf("binary representation of 256:\n");
for(i = 15; i>=0 ; i--) //assuming that the number wont have more than
// 15 DIGITS
{
f=f>>i;
b.a = f;
//d= d>>1;
f=d;
printf("%d",b.a);
}
return 0;
}

Array value getting changed

So I have two problems:
I'm using netbeans to code this.
The first is that the array value that I am setting in c.sArr is getting changed from 7 to some random number, and I can't figure out why.
The second is that when I try to run debug in netbeans, the code gives me a segfault, whereas when i run it normally it doesn't. It gives a segfault at the atoi function.
Whats going on here?
#include <stdio.h>
#include <stdlib.h>
#include "spoonMatrix.c"
int main(int argc, char** argv) {
int iterations;
int argCounter = 0;
int debug = 1;
int i,j,q;
if(argc < 2)
return -1;
if(debug == 1){
for(q=0;q<argc;q++)
printf("%s\n", argv[argCounter++]); //Checking the params
}
argCounter = 1;
iterations = atoi(argv[argCounter++]);
if(debug == 1)
printf("%d", iterations);
for(i=0;i<iterations;i++){
int rows = 0;
int columns = 0;
int m = 0, n, p, elemCount;
int posCount = 0;
int temp;
cm c;
c.row = rows;
c.column = columns;
c.elems = (char*)calloc(rows*columns, sizeof(char));
c.sArr = (int*)calloc(rows*columns, sizeof(int));
rows = atoi(argv[argCounter++]);
columns = atoi(argv[argCounter++]);
for(m=0;m<rows*columns;m++)
{
c.sArr[m] = -2;
//printf("Here");
}
if(debug == 1)
{
printf("Rows : Columns - %d : %d\n", rows, columns);
}
temp = argCounter;
printf("argCounter is: %d\n", argCounter);
for(elemCount = 0 ; argCounter < temp + rows; argCounter++)
{
for(n=0; n<columns; n++, elemCount++)
{
c.elems[elemCount] = argv[argCounter][n];
//if(debug == 1)
// printf("%c\t", c.elems[elemCount]);
if(c.elems[elemCount]== 's' || c.elems[elemCount] == 'S')
{
c.sArr[posCount] = elemCount;
printf("%c\t%d\t%d\t%d\n", c.elems[elemCount], elemCount, c.sArr[posCount++], posCount);
}
}
}
printf("%d\n", c.sArr[0]);
if(debug == 1)
{
for(j=0; j<rows*columns; j++)
{
printf("%c ", c.elems[j]);
}
printf("\n");
for(j=0;j<rows*columns;j++)
{
printf("%d ", c.sArr[j]);
}
}
}
return (EXIT_SUCCESS);
}
and
the other file is:
struct charMat{
int row;
int column;
char* elems;
int* sArr;
};
typedef struct charMat cm;
Coded in the hurry, excuse the weird debugging statements.
Thanks
You aren't allocating (enough) memory:
int rows = 0;
int columns = 0;
c.elems = (char*)calloc(rows*columns, sizeof(char)); // rows * columns is 0
c.sArr = (int*)calloc(rows*columns, sizeof(int)); // rows * columns is 0
rows = atoi(argv[argCounter++]);
columns = atoi(argv[argCounter++]);
From calloc:
If the size of the space requested is 0, the behavior is
implementation-defined: the value returned shall be either a null
pointer or a unique pointer.

Resources