I've made a shuffling type program that obtains from cases[]; and arranges them in a random order.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void deal(void);
int cases[22] = {1,2,3,4,5,6,8,10,15,20,25,35,50,65,85,100,105,135,165,200,250};
int main()
{
srand(time(NULL));
int a = 0;
deal();
for(a = 0 ; a < 22 ; a++)
printf("%d \n", cases[a]);
return 0;
}
void deal(void){
int loop;
int temp;
int x;
int y;
for(loop = 0; loop < 50; loop++){
x = rand() % 22;
y = rand() % 22;
temp = cases[x];
cases[x] = cases[y];
cases[y] = temp;
}
}
However when I run the code it comes with a randomly placed 0. Where is it from and why is it there?
Example output:
6
15
0 //I don't want that
20
5
50
10
3
165
65
135
105
8
1
200
25
100
85
2
250
4
You declared int cases[22] but initialized only 21 integers into that array and therefore, the last element will be 0 when not initialized. Try to add another integer at the end of the array
It's an off by one error: Ferico Samuel's answer is correct
This is a complement:
Instead of hard coding 22 as the number of cases you should write your program like this:
// no explicit declaration of the size here. The compiler automatically
// puts the correct size depending on the number of elements that follow.
int cases[] = {1,2,3,4,5,6,8,10,15,20,25,35,50,65,85,100,105,135,165,200,250};
...
for(a = 0 ; a < sizeof(cases) / sizeof(cases[0]); a++)
...
sizeof(cases) is the size of your cases array in bytes
sizeof(cases[0]) is the size of one element of the casesarray
thus sizeof(cases) / sizeof(cases[0])is the number of elements of the array.
This way you can add more elements to the cases array without the need to change the array size elsewhere in your program.
You declare your array as:
int cases[22] = {1,2,3,4,5,6,8,10,15,20,25,35,50,65,85,100,105,135,165,200,250};
Without you know it, there is actually only 21 elements in that array. Thus, in C standard compilers, the non-initialized value would be set as zero. To correct it, add one more element to the array.
int cases[22] = {1,2,3,4,5,6,8,10,15,20,25,35,50,65,85,100,105,135,165,200,250, 500}; // add 500
And things will be okay.
Anyway, for this kind of initialization, I recommend you to put the elements in multiple lines (say, every 10 elements):
int cases[22] = {1, 2, 3, 4, 5, 6, 8, 10, 15, 20,
25, 35, 50, 65, 85, 100,105,135,165,200,
250, 500}; // add 500
And put in nice format to avoid such error.
You have the wrong number of elements in the array. C is a bit stupid, because it is designed so that a compiler can only detect if there is too many elements in an array, but never if there is too few.
To ensure the exact amount of elements, you can declare arrays like this:
#define ARRAY_ITEMS(arr) (sizeof(arr) / sizeof(*arr))
#define CASES_ITEMS 22
int cases[] = {1,2,3,4,5,6,8,10,15,20,25,35,50,65,85,100,105,135,165,200,250};
_Static_assert(ARRAY_ITEMS(cases) == CASES_ITEMS, "Wrong array size: cases");
Related
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.
I am currently trying to learn about using pointers and functions together in C, which I don't think is easy.
I am trying to print the last element in an array, it actually does the opposite and prints the first element.
I know people normally use for loops, but I can't figure out how to do that with exactly this kind of problem and therefore I thought that I would try it out with an if statement instead.
Edit:
Why is if statement not working in this case? It seems logic that it should work...
My main.c file:
#include <stdio.h>
#include <stdlib.h>
#include "functions.h"
#define Size 7
int main(void)
{
int array1[] = { 11, 88, 5, 9, 447, 8, 68, 4 };
maxValue(array1, Size);
return 0;
}
My functions.h file:
#pragma once
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
int maxValue(const int *, int);
#endif
My functions.c file:
#include "functions.h"
#include <stdio.h>
#include <stdlib.h>
int maxValue(const int *array1, int Size)
{
int max = array1[0];
if (max < array1[Size]) {
Size++;
max = array1[Size];
}
printf("Max value: %d \n", max);
}
Why is if statement not working in this case? It seems logic that it should work...? Because here
if (max < array1[Size]) { }
Size is defined as 7 and you are comparing array1[0] with array1[7] i.e 11 < 4 -> false, hence it doesn't enter into if block, so the last printf executes and that prints max. But its not a correct logic if if blocks becomes true then further Size++ will cause accessing out of bound array elements which cause undefined behavior.
int maxValue(const int *array1, int Size)
{
int max = array1[0];
if (max < array1[Size]) { /* 11 < 4 false, skips if block */
//Size++; /* this is wrong as Size++ here and next accessing array1[Size] cause UB due to accessing out of bound array element */
max = array1[Size];
}
printf("Max value: %d \n", max); /* max is stills array1[0] i.e 11 */
}
Let's simulate what the CPU does when it enters the maxValue function with those arguments. 1. The variable max is assigned the value of array1[0], which is 11.
2. If max (11) is less than array1[7] (4). It is not, so the if block is not executed.
3. Print max: print 11.
Another thing: Your program causes undefined behaviour. Let's take an example where array1[0] is 3, instead of 11. The if block will be executed (3 < 4), so:
Size is incremented to 8.
max is assigned array1[8]. Since the last index in array1 is 7 (that is how you declared the array), you are accessing a memory adress which you are not supposed to access. This is undefined behaviour.
The names maxValue() and max are misleading and confusing what you are trying to do. lastValue() and last would make much more sense.
However what you are trying to do makes no sense in C because arrays are of known length, so you can access the last element directly:
int array1[] = { 11, 88, 5, 9, 447, 8, 68, 4 };
int array_length = sizeof(array1) / sizeof(*array1) ;
printf("Lastvalue: %d \n", array1[array_length - 1] ) ;
However you cannot do this in a function because arrays are not first class data types in C and when passed to a function will "degrade" to a simple pointer without any information regarding the size of the array pointed to. The calling function having the size information must pass that too (as you have done, but then appeared to get very confused):
void printLast( int* array, int length )
{
printf( "Lastvalue: %d \n", array1[length - 1] ) ;
}
It is difficult to see why you thought you might need any other code or what your maxValue() function is intended to achieve. The "logic" which you say "should work" is thus:
If value of the first array element is less than the value of the last array element, then print the undefined value one past the end of the array; otherwise print the first element of the array.
If you wanted to print the last element, then you simply print it, the value of the first element has nothing to do do with it. Either way you should not index past the end of the array - that value is undefined.
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}
I am trying to create an index array that will store the location of every ',' that is read in from a file. I have written the code and it seems to work but for some reason stops after exactly 1 ',' past the first line in the file.
What in the world is causing it to stop I cant figure it out. It just gives zeros after the first couple indexes.
#include <stdio.h>
#include <stdlib.h>
void getCommaIndex(int n,char table[],int index[]){
int i;
int p = 0;
for(i = 0 ; i < n ; i++){
if(table[i] == ','){
index[p] = i;
p++;
}
}
}
int main()
{
char table[100000];
int index[5000];
int i;
FILE *fp;
fp = fopen("C:/Users/Chris/Desktop/Open Frameworks/apps/myApps/bin/data/tableshort.csv","r");
while( !feof(fp)){
fgets(table,"%s",fp);
printf("%s",table);
getCommaIndex(5000,table,index);
}
for(i = 0 ; i < 11 ; i++){
printf("%d ",index[i]);
}
Output will look something like:
7 11 20 35 40 59 62 67 0 0 0 0 0 0
I just changed:
fgets(table,"%s",fp);
to:
fgets(table,5000,fp);
and everything worked.
See: http://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm
Also, your code in your question gave me this message in my compiler: warning: passing argument 2 of 'fgets' makes integer from pointer without a cast. Treat warnings as errors as much as you can.
Instead of reading the entire file at once, you could try reading a single line at a time. Also, in your getCommaIndex function table[] is 100000 but you only iterate over the first 5000 indices. It is not clear to me but it seems like you value for n should be 100000 so you loop over the entire table array.
I'm going to write in pseudo code to make my question more clear. Please keep in mind this code will be done in C.
Imagine I have an array of any amount of numbers. The first number tells me how big of an array we're dealing with. For example, if my first number is 3, it means I have two 3x3 matrices. So I create two multidimensional arrays with:
matrix1[3][3]
matrix2[3][3]
What I'm having a hard time with is the arithmetic/coding to assign all the numbers to the matrices, I'm having a very hard time visualizing how it would be done.
Imagine a test array contains [2,1,2,3,4,5,6,7,8]
My program should now have two matrixes with:
1 2 5 6
3 4 7 8
Do I need several nested loops? Any help would be appreciated.
At the moment the only idea i get is using two for loops. Or you can make a function and call it every time you need (but don't forget to use k as second argument).
int i, j, k;
/* We start in the 2nd element of the array that's why k = 1. */
k = 1;
/* Now we fill the array1 copying 1 by 1 the elements of the "test array" until
we fill it. Then we do the same with the array2. */
for( i = 0; i < test[ 0 ]; i++ ){
for( j = 0; j < test[ 0 ]; j++ ){
array1[ i ][ j ] = test[ k ]
k++;
}
}
for( i = 0; i < test[ 0 ]; i++ ){
for( j = 0; j < test[ 0 ]; j++ ){
array2[ i ][ j ] = test[ k ]
k++;
}
}
Your data is presented in row-major order. After reading your integer array and validating the content (i.e. the dim=4 means 32 values follow, dim=2 means 8 values follow, etc.) I'm not sure why you want to allocate or loop anything.
I.e. You can use your physical test[] data as the matrices:
int dim = test[0];
int (*mat1)[dim] = (int (*)[dim])(test+1);
int (*mat2)[dim] = (int (*)[dim])(test+1 + dim*dim);
C99 supports variable array declarations at the implementation level (i.e. the compiler can support the feature as it is defined by the standard, but does not have to; see 6.7.6.2 of the C99 standard for more info). If your toolchain does NOT support it, then a predefined macro, __STDC_NO_VLA__ must be defined and can be tested at compile time (see section 6.10.8.3-1 of the C99 standard). That being said, every C99-compliant compiler I've ever used in the last decade-plus does support it, so if your's does not, tell us below in a comment.
If it does, then pay note to the use of 'dim' in the declarations of mat1 and mat2 above). It is one of the few features of C I like that C++ does not have. So dance with the one you brought.
Finally, assuming your compiler is C99 compliant and supports VLAs (__STDC_NO_VLA__ is NOT defined), as an extra super-special bonus it is all-but-guaranteed to be the fastest algorithm to get your two matrices, because there is no algorithm. You read one array element, then assign two pointers. O(3) is hard to beat.
Example
#include <stdlib.h>
#include <stdio.h>
// main loader.
int main(int argc, char *argv[])
{
int test[] = {2,1,2,3,4,5,6,7,8};
int dim = test[0];
int (*mat1)[dim] = (int (*)[dim])(test+1);
int (*mat2)[dim] = (int (*)[dim])(test+1 + dim*dim);
// proof stuff is where it should be.
int i=0,j=0;
for (i=0;i<dim;i++)
{
for (j=0;j<dim;printf("%d ", mat1[i][j++]));
printf (" ");
for (j=0;j<dim;printf("%d ", mat2[i][j++]));
printf("\n");
}
return EXIT_SUCCESS;
}
Output
1 2 5 6
3 4 7 8
A similar test with a 3x3 data set:
int test[] = {3,1,2,3,4,5,6,7,8,9,9,8,7,6,5,4,3,2,1};
Output
1 2 3 9 8 7
4 5 6 6 5 4
7 8 9 3 2 1
And finally, a 4x4 data set:
int test[] = {4,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1};
Output
1 2 3 4 8 7 6 5
5 6 7 8 4 3 2 1
1 2 3 4 8 7 6 5
5 6 7 8 4 3 2 1
The problem with multidimensional arrays in C is that you need to know in advance (at compile time) n-1 of the dimension sizes, they are also a drag when used as function parameters.
There are a couple of alternate approaches:
Creating an array of arrays. i.e. allocating an array of array pointers and then allocating arrays to those pointers.
type **array = malloc(sizeof(type * ) * < firstnumread > );
array[0] = malloc(sizeof(type) * < firstnumread > );
...
Allocating a single dimension array with the size of all the multiplied dimensions. i.e.
type *array = malloc(sizeof(type) * < firstnumread > * < firstnumread >);
In your case, the second is probably more appropiate. Something like:
matrix1 = malloc(sizeof(type)*<firstnumread>*<firstnumread>);
matrix2 = malloc(sizeof(type)*<firstnumread>*<firstnumread>);
Then you can assign values like this:
matrix1[column*<firstnumread> + row] = <value>;
Yes, with 2 for loops.
2D arrays are stored in continuous series of lines from the matrix. So you doesn't even need to allocate new memory you can use your original array. Anyway you can create 2 new standalone array too.
You can crate a function like this, to get the correct number of the matrix.
int getNumber(int array[], int arraynumber, int index_x, int index_y)
{
return array[(((array[0]*index_x)+index_y)+1)+((array[0]*array[0])*arraynumber)];
}
The arraynumber variable is 0 for the first and 1 for the second matrix. This funciton works only if all parameters are correct, so ther is no error detection.
With this function you can easily loop through and create 2 new arrays:
int i,k;
for (i=0; i<array[0]; i++)
{
for (k=0; k<array[0]; k++)
{
newarray1[i][k] = getNumber(array, 0, i,k);
newarray2[i][k] = getNumber(array, 1, i,k);
}
}
Here is something that works in a single loop; no nests and no repeats. I don't know if it'll outperform other answers, but I just felt like giving you a different answer ^_^
I have not tested this code, but it looks like the logic of the algorithm works - that's the point, right? Let me know if it has any errors....
int c=0, x=0, y=0, size=test[0], length=sizeof(test);
for(i=1; i<length; i++) {
if((c-size)<0) {
matrix1[x][y] = test[i];
} else {
matrix2[x][y] = test[i];
}
++y;
if(y%size == 0) {
++c;
y = 0;
x = (c-size)<0 ? ++x : 0;
}
}