Changing array values in functions - c

Ok so I have a 10x10 array that I need to flip and print. I made this function to do just that
void flip(int d[][10], int rows)
{
int temp, x, y, cols;
cols=rows;
for(x=0; x<rows; x++)
{
for(y=0; y<cols; y++)
{
temp=d[x][y];
d[x][y]=d[y][x];
d[y][x]=temp
}
}
}
Now I know arrays are passed by reference but I also read somewhere that arrays itself act as pointers so you don't have to use pointer notation which seems right. My problem is that when I try to print after flipping it, it does not print the flipped array, but prints out the original one making me think that it isn't flipping the original array.
Here is the print function.
void printArray(int d[][10])
{
int rows, cols,x,y;
rows = sizeof(d[0])/sizeof(d[0][0]);
cols = rows;
for(x=0;x<rows; x++)
{
for(y=0;y<cols;y++)
printf("%2d ",d[x][y]);
printf("\n");
}
}
Odd thing is if I change temp into a "hard" value like the number 10, then it does print out a 10x10 array with half of them being 10s. I am at a loss here why the simple swapping isn't working :(

From what I can tell, by "flip" you mean "transpose"...
Also, if you work out the code by hand, your code works, but twice - aka, you get the original matrix. You can try changing the inner for loop to start at x, not zero.

Related

Weird array behaviour in C

so I'm trying to write a simple function that fills a given area of the screen with 'X's. The Area to be filled is user defined.
As (later on) I want to be able to manipulate that display, the 'x's are written into an array. Then, I use this array for my printf().
This works perfectly fine most of the time, but there are two problems:
In some cases ( for Example with the values 5,10) one X is missing from the array! (In this case drawPic[8][0] ) It doesn't make any sense to me...
X X X X X
X X X X X
X X X X X
X X X X X
X X X X X
X X X X X
X X X X X
X X X X X
X X X X
X X X X X
Second, I sometimes get that nice segmentation fault: 11 error. I don't understand why this is the case, it seems quite random. (for example, values 5,12 will give error, values 10,12 will not)
/*
Testcase to fill a picture frame
*/
#include <stdio.h>
#define clrscr() printf("\e[1;1H\e[2J")
int main()
{
int sizeX, sizeY;
clrscr();
printf("\n\n\n\n\tEnter picture size (x,y):\t");
scanf("%d,%d", &sizeX, &sizeY);
char drawPic[sizeX-1][sizeY-1];
clrscr();
for(int i=0; i<sizeY; i++)
{
for(int j=0; j<sizeX; j++)
{
drawPic[i][j] = 'X';
if(j<sizeX-1)
printf("%c ", drawPic[i][j]);
else
printf("%c\n", drawPic[i][j]);
}
}
// printf("\n\n 9th line 1st char: %c\n\n", drawPic[8][0]);
}
/edit:
OKAY, first of all: thanks a lot. Array size was a typical noob mistake, i guess. Correct array size solved issue no.1, and the other problem was that i had i,j of drawPic the wrong way round.
Working code:
/*
Testcase to fill a picture frame
*/
#include <stdio.h>
#define clrscr() printf("\e[1;1H\e[2J")
int main()
{
int sizeX, sizeY;
clrscr();
printf("\n\n\n\n\tEnter picture size (x,y):\t");
scanf("%d,%d", &sizeX, &sizeY);
char drawPic[sizeX][sizeY];
clrscr();
for(int i=0; i<sizeY; i++)
{
for(int j=0; j<sizeX; j++)
{
drawPic[j][i] = 'X';
if(j<sizeX-1)
printf("%c ", drawPic[j][i]);
else
printf("%c\n", drawPic[j][i]);
}
}
}
You're a great community to help out beginners like me with their stupid mistakes which must seem so very obvious to you. Thanks a lot!
Your array is too small:
char drawPic[sizeX-1][sizeY-1];
This creates a 2D array with dimensions sizeX-1 and sizeY-1 which is one less than you requested. Because array indices in C start from 0, the valid indices for these dimensions are 0 to sizeX-2 and 0 to sizeY-2 respectively.
Your loops then use indices up to sizeX-1 and sizeY-1 which means you read and write outside the bounds of the array. This triggers undefined behavior which explains the occasional strange results you're seeing.
When declaring an array, the dimensions specify the total number of elements, not the index of the last element. So you instead should declare it as:
char drawPic[sizeX][sizeY];
You've also got your loop conditions mixed up:
for(int i=0; i<sizeY; i++)
{
for(int j=0; j<sizeX; j++)
{
i should have sizeX as its limit and j should have sizeY as its limit, not the other way around. This can also cause reading outside the array bounds when the two values are not the same. While it's probably not a problem in practice, there's no guarantee it won't be.

Trying to make a function which squares all values in an array. Getting strange number on the last value

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}

convert an array to multi dimensional C without using pointer

First of all, I would like to know if its possible. If so, please checkout my code and tell me what is wrong.
int m[n]; // this is where I pass the values to a array
for(int i=0;i<n;i++) {
scanf("%d",&a);
m[i]=a;
}
int v[n][b]; // this is where I pass the values from a array to a 2d array
for(int i=0;i<n;i++) { // but for some reason it doesnt work
for(int j=0;j<b;j++) {
v[i][j]=m[i];
}
}
}
The output is :
something like this
v[0][0]:0
v[0][1]:0
v[1][0]:1
v[1][1]:1
....
but I want something like this:
v[0][0]:0
v[0][1]:1
v[1][0]:2
v[1][1]:3
without repeating the values
P.S- if I need to use pointers you can also explain me that way but I would prefer the first one.
In assigning to v[i][j], you are constantly reassigning whatever value was in m[i].
Instead try:
v[i][j] = m[i*n + j];
This is only going to work if the array m has n*b elements.
i*n represents the row you're working on, and j is the column. Or vice-versa, it's up to you how you imagine it.
#include <stdio.h>
int main(){
int m[6]; // this is where I pass the values to a array
int i;
int j;
int k;
int a;
for(i=0;i<6;i++) {
scanf("%d",&a);
m[i]=a;
}
k=0;
int v[2][3]; // this is where I pass the values from a array to a 2d array
for(i=0;i<2;i++) { // but for some reason it doesnt work
for(j=0;j<3;j++) {
v[i][j]=m[3*k+j]; // 3 is the maximum i value [n of your code]
}
k++;
}
return 0;
}
Just used OP's code and changed:
1) Defined all integer variables.
2) the int inside the for removed to be compatible code with every c compiler (OP doesn't really need this changes)
3) Added a variable k that been increased with the changes of outer loop variable and used it in the command v[i][j]=m[3*k+j]; to give the appropriate m value to the new array. (3 been explained in the comment of the same line)
See #Pablo's comment for not using k
Assuming you have at least as many elements in your 1D array as your 2D array and you want to fill in your 2D array in row major order, it suffices to just increment an index for your 1D array every time you read an element from it.
int v[n][b];
int k = 0;
for(int i=0;i<n;i++) {
for(int j=0;j<b;j++) {
v[i][j]=m[k++];
}
}

finding how many times an element has repeated in c

I've got a c study which it must print all the numbers in an array then how many times they repeated.
int lottery(int a,int b,int c,int d,int e,int f,int i,int count)
{
printf("Enter the loop count:");
scanf("%d",&d);
a=time(NULL);
srand(a);
int genel[100][100];
int hepsi[50]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49};
count=0;
for(e=0;e<=d-1;e++)
{
for(b=0;b<=5;b++)
{
genel[e][b]=(rand()%49+1);
while(i>=0 && i<=49)
{
if(genel[e][b]==hepsi[i])
{
count=count+1;
}
else{
count=count;
}
}
printf("%d->%d\t",genel[e][b],count);
}
}
}
This doesnt work obviously. the output must be something like that
1-->0 2-->3 3-->15 etc
TY for your help, cheers :)
It is important that you understand what you are doing, naming is therefore very important. Nesting loops is okay if you know what you are doing. An easier to understand approach would be:
void lottery() {
int i, j //forloop counters
int randArray[100][100]; //array for random values
srand(Time(NULL)); //set random seed based on system time
//set random values
for(i = 0; i < 100; i++) {
for(j = 0; j < 100; j++) {
randArray[i][j] = rand()%49 + 1; //sets random ranging from 1 to 49 (49 incl)
}
}
//here you can start the counting procedure, which I won't spoil but ill give some hints below
}
There are a few options, first the easy lazy approach:
use a loop over all the values, 'int number' from 1 up to 49, inside that forloop use two forloops to search through the whole array, incrementing int x everytime you encounter the value 'number'. After youve searched through the whole array, you can use printf("%d -> %d", number, x); to print the value, set x to zero and count another number.
Another approach is as u tried,
create an array with for each number a location where you can increment a counter. Loop through the whole array now using two for-loops, increment the arraylocation corresponding to the value which youve found at randArray[i][j]. Afterwards print the array with counts using another forloop.
I suggest you try to clean up your code and approach, try again and come back with problems you encounter. Good luck!
sorry if this wasn't helpful to you, I tried to spoil not too much because according to my own experience programming should be learned by making mistakes.

Segmentation fault in C with only certain inputs

Okay, so I'm trying to solve the Knapsack problem.
On small input cases the program runs with no problem and provides the optimal solution, however when the input size is large, or rather the numbers in the input file become large, the program gives me a segmentation fault. I don't quite get why is this happening since the max value of INT exceeds any of these numbers too.
Here's my code.
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int W,n,i,j,k ;
scanf("%d %d",&W,&n); // capacity of knapsack and number of total items
int value[n+1],weight[n+1];
int** A;
A = (int **)malloc((n+1)*sizeof(int*));
for(i=0;i<W+1;i++)
A[i]=(int *)malloc(sizeof(int)*(W+1));
for(i=1;i<n+1;i++)
{
scanf("%d %d",&value[i],&weight[i]); //taking value and weight of each item
}
for(i=0;i<W+1;i++)
A[0][i]=0;
for(i=0;i<n+1;i++)
A[i][0]=0;
for(i=1;i<n+1;i++)
{
for(j=1;j<W+1;j++)
{
if(j-weight[i]<0)
{
A[1][j]=A[0][j];
}
else
{
if(A[0][j]>A[0][j-weight[i]]+value[i])
A[1][j]=A[0][j];
else
A[1][j]=A[0][j-weight[i]]+value[i];
}
}
for(k=0;k<W+1;k++)
A[0][k]=A[1][k];
}
int max=0;
i=1;
for(i=0;i<2;i++)
for(j=0;j<W+1;j++)
{
if(A[i][j]>max)
max=A[i][j];
}
printf("%d\n",max);
return(0);
}
It runs perfectly for this input http://spark-public.s3.amazonaws.com/algo2/datasets/knapsack1.txt
But when the input size is the one given in the link, it provides a seg fault http://spark-public.s3.amazonaws.com/algo2/datasets/knapsack2.txt
Thanks for the help!
When allocating the arrays for the 2nd dimension you do:
for(i=0;i<W+1;i++)
A[i]=(int *)malloc(sizeof(int)*(W+1));
It should be n+1 instead of W+1 in the loop. You should iterate over the "items" dimensions and allocate "weight" dimension.
The solution will work perfectly for n <= W, but for larger number of items (W < n) - you will get undefined behavior, because you are trying to access A[n][0] at some point, but you did not allocate the array for the nth item.
So basically - you need to change the initialization of the 2nd dimension to:
for(i=0;i<n+1;i++)
A[i]=(int *)malloc(sizeof(int)*(W+1));

Resources