Goodevening everyone, i'm learning now to loop an array of numbers, and i'm just wondering,
how can i square the numbers in my array depending on the input of how many times i should square it
int main() {
int nums[5] = {1, 2, 3, 4, 5};
int loop;
int a;`enter code here`
int pro,pro1,pro2,pro3,pro4;
int spacing = 3;
int i = 0
scanf("%d", &a);
do{
pro = pow(nums[0],2);
pro1 = pow(nums[1],2);
pro2 = pow(nums[2],2);
pro3 = pow(nums[3],2);
pro4 = pow(nums[4],2);
i++
}while (i != a);
printf("%0*d\n", spacing, pro);
printf("%0*d\n", spacing, pro1);
printf("%0*d\n", spacing, pro2);
printf("%0*d\n", spacing, pro3);
printf("%0*d\n", spacing, pro4);
return 0;
}
this is my code so far, i wanted to loop it, and get the results like this:
001
016
081
256
625
or like this
001
256
6561
65536
390625
but i always get this:
001
004
009
016
025
please help me understand thank you
There is a strong error and a number of possible improvements in your code.
The error has already be identified by #SylvainChaugny and is that you re-use original nums value on each and every iteration. The improvements are:
you are using 5 variables pro to pro5 and process them the same. Better to make an array for them, or even better re-use the nums array.
if you want to later extend your program to 6 values, you would have to consistently look through the code to search what needs to be changed: better to use a constant or as you have a literal initialization ask the size to the compiler
you are using pow to process integer values. This is not efficient because as pow takes and returns double values you force a conversion from int to double and back. In addition it might be dangerous for large values: a double has less precision than an int on 64 bits architectures (48 mantissa bits for a double, 64 bits for an int). So it can lead to incorrect results.
So your code could become:
#include <stdio.h>
int main() {
int nums[] = {1, 2, 3, 4, 5};
int len = sizeof (nums) / sizeof (*nums); // idiomatic way for the length of an array
int a;
int spacing = 3;
scanf("%d", &a);
for (int i=0; i<a; i++) {
for (int j=0; j<len; j++) {
nums[j] = nums[j] * nums[j];
}
}
for (int i=0; i<len; i++) {
printf("%0*d\n", spacing, nums[i]);
}
return 0;
}
It is shorter to type (not only laziness but also less sensitive to typos) and it gives the expected result ;-). In addition, if you want to add a value to the array, it can be done be changing one single line.
Your problem is that you always reassign your pro variables to the exact same value (pow(nums[0], 2), pow(nuws[1], 2), ....
So no matter what the value of a is, you always will have your pro3 variable to be equal to pow(nums[3], 2).
You first have to assign the initial values to your pro variables, then use them in the calls to pow(), to be able to square your previous result.
Related
I have to find the largest product of 13 adjacent numbers of a 1000-digit number below. My code for the problem is as follows:
#include <stdio.h>
int main()
{
char arr[1000] =
"731671765313306249192251196744265747423553491949349698352031277450"
"632623957831801698480186947885184385861560789112949495459501737958"
"331952853208805511125406987471585238630507156932909632952274430435"
"576689664895044524452316173185640309871112172238311362229893423380"
"308135336276614282806444486645238749303589072962904915604407723907"
"138105158593079608667017242712188399879790879227492190169972088809"
"377665727333001053367881220235421809751254540594752243525849077116"
"705560136048395864467063244157221553975369781797784617406495514929"
"086256932197846862248283972241375657056057490261407972968652414535"
"100474821663704844031998900088952434506585412275886668811642717147"
"992444292823086346567481391912316282458617866458359124566529476545"
"682848912883142607690042242190226710556263211111093705442175069416"
"589604080719840385096245544436298123098787992724428490918884580156"
"166097919133875499200524063689912560717606058861164671094050775410"
"022569831552000559357297257163626956188267042825248360082325753042"
"0752963450";
int i, j;
long int max;
max = 0;
long int s = 1;
for (i = 0; i < 988; i++) {
int a = 0;
for (j = 1; j <= 13; j++) {
printf("%c", arr[i + a]);
s = s * arr[i + a];
a++;
}
printf("%c%d", '=', s);
printf("\n");
if (s > max) {
max = s;
}
}
printf("\nMaximum product is %d", max);
getchar();
}
Some outputs are zero even if none of the input is zero. The second output happens to be negative. The answers don't even match. Any help is appreciated.
Many set of 13 digits in your char array arr contains zeroes and that is why the multiplication of these sets will result in 0.
There are a couple of issues with your code:
You are using %d instead of %ld to print long int. Using the wrong conversion specifier will result in undefined behaviour.
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
You are not converting the ASCII value of the digit into its actual value before multiplication. (ASCII value of '0' is 48). This results in integer overflow and is the cause for negative values to be printed.
So the statement:
s = s * arr[i + a];
should be changed to:
s = s * (arr[i + a] - '0');
You are also not resetting the product s to 1 at the beginning of the inner for loop and because of this, you end up multiplying values from the results of different sets of 13.
After making these changes, you can see the live demo here.
There are a few issues to tackle in this code:
Clean up spacing and variable names (an edit by another user helped resolve this issue). Remove redundant variables like a, which j could easily represent by iterating from 0 to 12 rather than 1 to 13. This seems cosmetic but will make it easier for you to understand your program state, so it's actually critical.
Numerical overflow: As with all PE problems, you'll be dealing with extremely large numbers which may overflow the capacity of the long int datatype (231 - 1). Use unsigned long long to store your max and s (which I'd call product) variables. Print the result with %llu.
Convert chars to ints: arr[i+j] - '0'; so that you're multiplying the actual numbers the chars represent rather than their ASCII values (which are 48 higher).
s (really product) is not reset on each iteration of the inner loop, so you're taking the product of the entire 1000-sized input (or trying to, until your ints start to overflow).
int squaring_function (int *array, int i);
int main()
{
int array[5];
int i;
for(i=0; (i <= 5) ; i++)
{
array[i] = i;
printf("\nArray value %d is %d",i,array[i]);
}
for(i=0; (i <= 5) ; i++)
{
array[i] = (squaring_function(array, i));
printf("\nSquared array value %d is %d",i,array[i]);
}
return 0;
}
int squaring_function (int *array, int i)
{
return pow((array[i]),2);
}
I'm trying to use this squaring_function to square each value in turn in my array (containing integers 0 to 5). It seems to work however the last value (which should be 5)^2 is not coming up as 25. cmd window
I have tried reducing the array size to 5 (so the last value is 4) however this prints an incorrect number also.
I'm quite new to C and don't understand why this last value is failing.
I'm aware I could do this without a separate function however I'd quite like to learn why this isn't working.
Any help would be much appreciated.
Thanks,
Dan.
There are 2 bugs in your code. First is that you're accessing array out of bounds. The memory rule is that with n elements the indices must be smaller than n, hence < 5, not <= 5. And if you want to count up to 5, then you must declare
int array[6];
The other problem is that your code calculates pow(5, 2) as 24.99999999 which gets truncated to 24. The number 24 went to the memory location immediately after array overwriting i; which then lead to array[i] evaluating to array[24] which happened to be all zeroes.
Use array[i] * array[i] instead of pow to ensure that the calculation is done with integers.
The code
int array[5];
for(int i=0; (i <= 5) ; i++)
exceeds array bounds and introduces undefined behaviour. Note that 0..5 are actually 6 values, not 5. If you though see some "meaningful" output, well - good or bad luck - it's just the result of undefined behaviour, which can be everything (including sometimes meaningful values).
Your array isn't big enough to hold all the values.
An array of size 5 has indexes from 0 - 4. So array[5] is off the end of the array. Reading or writing past the end of an array invokes undefined behavior.
Increase the size of the array to 6 to fit the values you want.
int array[6];
The other answers show the flaws in the posted code.
If your goal is to square each element of an array, you can either write a function which square a value
void square(int *x)
{
*x *= *x;
}
and apply it to every element of an array or write a function which takes an entire array as an input and perform that transformation:
void square_array(int size, int arr[size])
{
for (int i = 0; i < size; ++i)
{
arr[i] *= arr[i];
}
}
// ... where given an array like
int nums[5] = {1, 2, 3, 4, 5};
// you can call it like this
square_array(5, nums); // -> {1, 4, 9, 16, 25}
My problem is that i dont know what this functions do, thats program
from my teacher(not whole program just functions). Just wanna ask you what this functions do, mainly why
i store my number from right to left at string? thanks
#include<stdio.h>
#include<string.h>
#define MAX 1000
void str_to_num(char *str, char *number, int *dlzka)
{
int i;
for(i=0; i < MAX; i++)
number[i] = 0;
*dlzka = strlen(str);
for(i = 0; i < *dlzka; i++)
cis[(*dlzka) - 1 - i] = str[i] - '0';
}
void plus(char *cislo, int *d1, char *cis2, int d2)
{
int i; prenos = 0;
if(*d1 < d2)
*d1 = d2;
for(i = 0; i < *d1; i++)
{
pom = number[i] + number[i];
pom += prenos;
number[i] = pom % 10;
prenos = pom / 10;
}
}
Here is the lesson your teacher should be teaching:
There is a difference between the numerical value of 1, and the computer code (ASCII for example) that is used to represent character 1 displayed on the screen or typed on the keyboard.
Every time you see 1 on the screen, your computer sees 49 in memory.
0 is 48, 2 is 50 and so on.
Conveniently, all digit characters are arranged in a sequence from 0 to 9, so to convert their character codes to their numeric values all you have to do is subtract the character code of zero to get the digit position in the sequence.
For example: 49 - 48 = 1 --> '1' - '0' = 1
And this is how the first function, str_to_num works.
C language does not provide a variable large enough to work with 100 digit numbers, so you need to sum them up one digit at a time.
The second function has completely wrong variable names, but it is still pretty obvious what it is trying to do:
It sums up two single digit numbers, then stores the ones part of the result in an array and the tenth (if sum is > 9) in a helper variable.
As already suggested in the comments, this is how you sum up numbers manually on a page one digit at a time.
I don't know what prenos means in your language, but in English this variable should be called carry and it keeps the overflowing tens digit for the next round.
There is however something missing from the sum function: if the sum of the last (leftmost) two digits is more than 9, the extra 1 will be lost, and the result will be wrong.
Check the original code your teacher gave you - either you copied it wrong, or he is giving a bad example.
I wrote two functions and call the functions in main.
Function 1 – I wrote a function that returns void and takes an int * (pointer to integer array) or int[], and int (for the size). The function needs to initialize all the elements of the array to non-zero values.
Function 2 – I wrote another function that returns int and takes an const int * (pointer to integer array) or int[], and int (for the size). The function should sum all the elements of the array and return the sum.
In main I defined an integer array of size 5. Called function 1 in main to initialize the values of the array. Called function 2 in main to get the sum and print the value of the sum to the console.
My problem is the program runs but the print out for sum we are getting is a large (in the millions), random, number and is not the expected answer of 15. Anyone who can help us get the correct answer would be greatly appreciated
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#pragma warning(disable: 4996)
void func1(int* ptr, int size);
int func2(const int* ptr, int size);
int main()
{
int grid[5];
func1(grid, 5);
func2(grid, 5);
}
void func1(int* ptr, int size)
{
*ptr = 1, 2, 3, 4, 5;
}
int func2(const int* ptr, int size)
{
int sum;
sum = ptr[0] + ptr[1] + ptr[2] + ptr[3] + ptr[4]; // *(ptr + 0); putting an asterisk makes it so that it changes the entire "ptr" value and the "[0]" value
printf("\n\nThe sum of the integers in the array is %d.\n\n", &sum);
}
*ptr = 1, 2, 3, 4, 5;
does not do what you think it does. It actually evaluates all the integer constants but sets ptr[0] to be 1 (see comma operator for more detail), leaving all the others at some arbitrary value.
Note that it is not evaluating *ptr = (1, 2, 3, 4, 5) (which would set *ptr to 5) but is actually evaluating (*ptr = 1), 2, 3, 4, 5 - this works because something like 42 is actually a valid C statement, albeit not very useful.
If you're trying to set the array to increasing values, just use something like:
for (int i = 0; i < size; i++)
ptr[i] = i + 1;
You probably also want to do that when summing the values since it should depend on the passed-in size rather than just summing five values:
int sum = 0;
for (int i = 0; i < size; i++)
sum += ptr[i];
Additionally, the value you are printing out is not the sum, it's the address of the variable containing the sum (a decent compiler will warn you about this). You should be using sum in your printf rather than &sum.
And, as a final note, the signature for func2 indicates that you should actually be returning the sum rather than just printing it. So I would suggest removing the printf from that function and simply doing:
return sum;
Then you can put the printf into the caller (main) as follows:
int main(void)
{
int grid[5];
func1(grid, sizeof(grid) / sizeof(*grid));
int sum = func2(grid, sizeof(grid) / sizeof(*grid));
printf("The sum of the integers in the array is %d.\n\n", sum);
return 0;
}
Note the use of sizeof(grid) / sizeof(*grid), which is basically the number of array elements in grid - this will allow you to resize grid by simply changing it in one place to something like int grid[42] and still have all the code work with the updated size.
Not actually necessary for your code but it's best to get into good programming habits early (more descriptive names for your functions may also be a good idea).
Line *ptr = 1, 2, 3, 4, 5; assigns ptr[0] value and leaves other spots unitilized so when you sum it, it will be random memory.
You should use for like this to initialize
for(int i=0;i<size;i++)
{
ptr[i] = i+1;
}
and similiar aproach to sum it.
I'm writing a program that finds the summation of prime numbers. It must use redirected input. I've written it so that it finds the largest number for the input then uses that as the nth prime. It then uses the nth prime to set the size of the array. It works up until I try to printf the sum. I can't figure out why I'm getting a seg fault there of all place.I think I've allocated the arrays correctly with malloc. why would the fault happen at printf on not when I'm using my arrays? Any suggestions on my code are also welcome.
EDIT
used a test input of 2000 form 1 to 2000 and it worked but the full test file of 10000 form 1 to 10000 crashes still looking into why. I'm guessing I didnt allocate enough space
EDIT
My problem was in my sieve I didnt take the sqrt(nthprime) so it found more primes then the array could hold
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int nprime (int max);
void sieve_sum ( int *primes, int nthprime, int tests,int *input);
int main(void)
{
int i=0;
int max=0; //largest input
int tests; //number of tests
int nthprime; //estimated nth prime
int *primes; //array of primes
int *input; // numbers to put in to P(n), where p(n) is the summation of primes
scanf("%d",&tests); //gets number of tests
input = malloc(sizeof(int)*tests);
//test values
for(i=0; i<=tests-1; i++)
scanf("%d",&input[i]);
//finds max test value
i=0;
for (i = 0; i < tests; i++ )
{
if ( input[i] > max-1 )
max = input[i];
}
// calls nprime places value in n
nthprime = nprime(max);
primes = malloc(sizeof(int)*nthprime);
// calls sieve_sum
sieve_sum( primes, nthprime, tests, input);
//free memory
free(input);
free(primes);
return 0;
}
//finds Primes and their sum
void sieve_sum ( int *primes, int nthprime, int tests,int *input)
{
int i;
int j;
//fills in arrays with 1's
for(i=2; i<=nthprime; i++)
primes[i] = 1;
//replaces non primes with 0's
i=0;
for(i=2; i<=sqrt(nthprime); i++)
{
if(primes[i] == 1)
{
for(j=i; (i*j)<=(nthprime); j++)
primes[(i*j)] = 0;
}
}
//rewrites array with only primes
j=1;
i=0;
for(i=2; i<=nthprime; i++)
{
if(primes[i] == 1)
{
primes[j] = i;
j++;
}
}
//sums
i=0;
for ( i=1; i<=tests; i++ )
{
int sum=0;//sum of primes
j=0;
for(j=1; j<=input[i-1]; j++)
{
sum = primes[j] + sum;
}
printf("%d\n", sum );
}
return 0;
}
//finds the Nth number prime
int nprime (int max)
{
//aproximization of pi(n) (the nth prime) times 2 ensures correct allocation of memory
max = ceil( max*((log (max)) + log ((log (max)))))*2;
return (max);
}
Example input file:
20
1
2
3
4
5
6
7
8
9
10
10
9
8
7
6
5
4
3
2
1
Example output should be:
2
5
10
17
28
41
58
77
100
129
129
100
77
58
41
28
17
10
5
2
OK, so I'm going to have a shot at this without saying too much because it looks like it might be a homework problem.
My best guess is that a lot of people have shied away from even looking at your code because it's a bit too messy for their level of patience. It's not irredeemable, but you would probably get a better response if it were considerably cleaner.
So, first, a few critical comments on your code to help you clean it up: it is insufficiently well-commented to make your intentions clear at any level, including what the overall purpose of the program is; it is inconsistently indented and spaced in an unconventional manner; and your choice of variable names leaves something to be desired, which is exacerbated by the absence of comments on variable declarations.
You should compile this code with something like (assuming your source file is called sumprimes.c):
gcc -std=c99 -pedantic -Wall -Wextra -o sumprimes sumprimes.c -lm
Have a look at the warnings this produces, and it will alert you to a few, admittedly fairly minor, problems.
The major immediate issue that I can see by inspection is that your program will certainly segfault because the storage that you have allocated with malloc() is too small by a factor of sizeof(int), which you have omitted.
A static error-checker like splint would help you detect some further issues; there's no need to slavishly follow all of its recommendations, though: once you understand them all, you can decide which ones to follow.
A few other remarks:
“Magic numbers”, such as 100 in your code, are considered very bad form. As a rule of thumb, the only number that should ever appear in code literally is 0 (zero), and then only sometimes. Your 100 would be much better represented as something named (like a const int or, more traditionally, a #define) to give an indication of its meaning.
It is unconventional to “outdent” variable declarations in the manner done in your code
If a function is advertised to return a value, you should always check it for errors, e.g. make sure that the return value of malloc() is not NULL, check that the return value of scanf() (if you use it) is the expected value, etc.
As a general matter of style, it is usually considered good practice in C to declare variables one per line with a short explanatory comment. There are exceptions, but it's a reasonable rule-of-thumb.
For any kind of input, scanf() is a poor choice because it alters the state of stdin in ways that are difficult to predict unless the input is exactly as expected, which you can never depend on. If you want to read in an integer, it is much better to read what's available on stdin with fgets() into a buffer, and then use strtol(), as you can do much more effective error-checking and reporting that way.
It is not recommended to cast the return of malloc() any more.
Hope this helps.