Number spiral in C, code not working - c

I want to make a spiral in C using a 2D matrix, such as the one shown below:
This is the code that I worked out. But it keeps going into an infinite loop. I can't seem to get an output. Can anyone tell me what mistake I'm making in this logic?
And I know its pretty cumbersome, but the assignment is to get the output for any "n" dimensional array, and we need to use all the row_left,row_right, etc variables, as they're given in the question.
#include<stdio.h>
int main(void)
{
int array[6][6]={1},dim,row_right=0,row_left=dim-1,col_up=0,col_down=dim-1;
int i,j,num,cnt;
printf("Enter the dimensions of 2D array:\n");
scanf("%d",&dim);
num=dim*dim;
cnt=0;
while(cnt!=num)
{
for(j=col_up;j<=col_down;j++)
{
if(j=0)
array[row_right][j]=1;
else
array[row_right][j]=array[row_right][j-1]+1;
}
for(i=row_right+1;i<=row_left;i++)
array[i][col_down]=array[i-1][col_down]+1;
for(j=col_down-1;j>=col_up;j--)
array[row_left][j]=array[row_left][j+1]+1;
for(i=row_left-1;i>row_right;i--)
array[i][col_up]=array[i+1][col_up]+1;
row_right++;
row_left--;
col_up++;
col_down--;
cnt++;
}
for(i=0;i<dim;i++)
{
for(j=0;j<dim;j++)
printf("%d\t",array[i][j]);
printf("\n");
}
return 0;
}

if(j=0)
is almost surely wrong. This sets j to zero and always evaluates to a false condition. The correct condition uses j == 0.
Also, the code uses the variable dim before it is read by scanf.

You forgot to initialize the variable dim. That is used in following line :
int array[6][6]={1},dim,row_right=0,row_left=dim-1,col_up=0,col_down=dim-1;
With correctly formatted code you probably would have seen this.

Related

code with array subscript references and pointer dereferencing compiles and runs but the results are unexpected

Why this program can compiling and run but the result is out of my expectation?`
#include<stdio.h>
int main(void)
{
char *message="hello";
for(int i=0;*message!='\0';i++)
{
printf("%c",message[i]);
}
return 0;
}
But this one can meet my expection.(print "hello" rightly)
int main(void)
{
char *message="hello";
for(int i=0;*message!='\0';i++)
{
printf("%c",*message++);
}
return 0;
}
In the C language,arr[i] is equal to *arr.But in the cases I show above,the result is totally different,when I run them in the devc++.Due to my limited knowledge ,I can't understand this.
Because I'm a student who is going to be a freshman after this summer vacation and only have some konwledge about C language,please answer my question in a more acceptable way. Thanks in advance!
***sorry ,the problem is caused because of my carelessness.I have learned my mistake.
In the C language, arr[i] is equal to *arr....
No, *arr is equal to arr[0].
In your first example, you type message++ which make et points on the next character.
So, the first code can be corrected that way:
for(int i=0; message[i]!='\0'; i++)
{
printf("%c",message[i]);
}
And the second can be simplified: (you don't need i):
for( ;*message!='\0'; )
{
printf("%c",*message++);
}
In the first code, the pointer message isn't changed and what the pointer message points at is also not changed, so the condition *message!='\0' is always true (doing 'h'!='\0').
Therefore, i will continuously be incremented and become so large that message[i] goes out of a region where access is allowed.
The condition should be message[i]!='\0' to avoid this error.
If you want to stick to use * operator for some reason, it should be *(message+i)!='\0'.
I rewrite the program with a slightly different appearance
#include<stdio.h>
int main(void)
{
char *message="hello";
for(int i=0; 'h'!='\0';i++) // notice the change here
{
printf("%c",message[i]);
}
return 0;
}
You see the problem now?
*message is always h, it's not changing with the loop iteration. The comparison is meaningless here, it does not terminate the loop as expected.
You need to ensure that you change the pointer to the next address every time you iterate, to ensure you are checking the value of the next element.
You can make use of the index value, like
for(int i=0; * (message + i) !='\0';i++)

How can i copy the array to another array in reserved way with changing the sign

#include<stdio.h>
int main(void) {
int arr[7];
int i;
int copy[7];
int j;
int *ptr_copy;
int *ptr_arr;
ptr_arr=&arr[0];
ptr_copy=&copy[0];
printf("Enter 7 Element In the Array");
for(i=0;i<7;i++)
scanf("%d",&ptr_arr[i]);
printf("\n");
for(i=7,j=0;i>=0;i--,j++)
ptr_copy[j]=ptr_arr[i];
for(i=0;i<7;i++)
ptr_copy[i]=ptr_copy[i]*-1;
printf("%d",ptr_copy[i]);
}
In the last loop I thought if I multiply the loop by -1 all the numbers' signs will change, is that correct? And in the last loop I'm not sure if it's correct. Could you help me and tell me where is the mistake?
You have undefined behaviour in this code . As you access index out of bound here -
for(i=7,j=0;i>=0;i--,j++)
ptr_copy[j]=ptr_arr[i];
ptr_array[7] isn't there . Array is till index 6. ptr_arr[7] contains garbage or whatever.
Change this loop to this (start from i=6)-
for(i=6,j=0;i>=0;i--,j++)
ptr_copy[j]=ptr_arr[i];
Also need a {} here -
for(i=0;i<7;i++){
ptr_copy[i]=ptr_copy[i]*-1;
printf("%d",ptr_copy[i]);
}
The problem is that you didn't put { } around the body of the last loop. So the printf is not part of the loop, it's run when the loop is done. And when the loop is done the value of i is 7, which is outside the bounds of the array.
This became obvious once I used my editor's indent command to reformat the code.
It should be:
for(i=0;i<7;i++) {
ptr_copy[i]=ptr_copy[i]*-1;
printf("%d",ptr_copy[i]);
}
I recommend you always put braces around the bodies of your if, while, for, etc. even if they only have one line.
See Why is it considered a bad practice to omit curly braces?

printing values of dynamic array

I have made a dynamic array of integers in C, here is my code
#include <stdio.h>
int main(){
int count=0, i, input;
int *myarr;
myarr=(int*)malloc(4*sizeof(int));
while(1){
scanf("%d", &input);
myarr[count]=input;
count++;
if (input == -1) break;
}
for (i=0; i<count; i++){
printf("%d ", myarr[i]);
}
return 0;
}
From the code, I thought i clearly made an array of 4 integers only i.e myarr[0] up to myarr[3], how come when i insert even 10 integers, it still prints all of them, it doesn't print garbage as i thought it would after the fourth integer... Maybe i didn't understand the point of dynamic creating an array?? Make me straight please!
You should only access myarr[0] up to and including myarr[3].
Accessing any other index is undefined behaviour: it might work, it might not.
Also, myarr[count]==input looks like a typo. Did you mean myarr[count] = input? The way you have it is testing if myarr[count] equals input. Technically the way you have it is undefined behaviour for any element of myarr since you are making use of uninitialised data.

Weird behavior of a counter inside the for loop

I've noticed that a counter(avariable) of the for loop, doesn't works well.
Indeed, the counter doesn't decrements correctly; I know this question seems stupid , but I can't understand why the a variable does this.
#include <stdio.h>
int main() {
int a,i,b,matrice[2][2];
printf("Put inside the matrix some numbers..\n");
for (a=2;a>=0;a--) {
for (b=2;b>=0;b--) {
matrice[a][b]=scanf("%d",&i);
}
}
return 0;
}
You are going out of bounds when you read into your array.
for (a=2;a>=0;a--) {
Array has only two elements, yet you try to read into the third on the first iteration.
matrice[2]
Is the third element. This happens for both dimensions.
scanf() call is not correct. It reads the value into i, but it returns the number of read items, not the value of i.
if you are trying to read the numbers into the matrix, then this is what you are supposed to do..
for (a=1;a>=0;a--) {
for (b=1;b>=0;b--) {
scanf("%d",&matrice[a][b]);
}
As the array matrice[2][2] has 2*2 elements, the valid indices are 0 and 1.
Thats why the for loop should start from 1 and not 2
1) The array index start from 0, as per your code it will access matrice[2][2] which will cause undefined behavior.
2) matrice[a][b]=scanf("%d",&i); will store the return value of scanf in matrice[a][b].
#include <stdio.h>
int main() {
int a,b,matrice[2][2];
printf("Put inside the matrix some numbers..\n");
for (a=1;a>=0;a--)
{
for (b=1;b>=0;b--)
{
scanf("%d",&matrice[a][b]);
}
}
//Then print or do other operations on matrice
return 0;
}
You are starting out of bounds.
For an array of size n you iterate from 0 to n-1
So what you want is
for (a=1;a>=0;a--){
for (b=1;b>=0;b--){
}
}
But one word of warning with running backwards with for loops. As is you are fine because you are using integers but if you were to do something like this
for (auto i = some_vector.size()-1;i>=0;i--){
}
You would be in a lot of trouble since i would not be able to take negative values as some_vector.size() is of type unsigned so the loop would never exit. I tend to always increment in a loop for this reason unless the logic dictates otherwise.
Your matrix has a size of [2][2] but you are using a loop that runs from 2 to 0 (inclusive). In an array of size 2 the maximum permissible index is 1.
I guess that you are just learning basic stuff.. so try to run this slightly version of your code:
#include <stdio.h>
int main() {
int a,i,b,matrice[2][2];
printf("Put inside the matrix some numbers..\n");
for (a=1;a>=0;a--) {
printf("a->%d\n", a);
for (b=1;b>=0;b--) {
printf(" b->%d\n", b);
scanf("%d",&matrice[a][b]);
}
}
printf("Check:\n");
for (a=1;a>=0;a--) {
for (b=1;b>=0;b--) {
printf(" [%d][%d]:%d\n", a, b, matrice[a][b]);
}
}
return 0;
}
In the first loop, the modified code run through the correct indices that for a 2x2 array are (0,0),(0,1),(1,0) and (1,1).
Please note that I have also modified the scanf part using the correct syntax: link.
The second loop is a simple test that what you've coded the data insertion correctly, by outputting the content of the matrix.

Why my code is getting Runtime error?

It took me 3 hrs to get the logic to solve the question and code accordingly. But now I am
getting this runtime error. Can anyone please help me to know what mistake I am doing ?
Edit : Its running now but not printing anything.
http://ideone.com/2YlS9J
#include <stdio.h>
#include<math.h>
float distance(float n1,float m1,float n2,float m2){
float d=0;float sum=0;
d =sqrt(pow(m2-m1,2)+pow(n2-n1,2));
sum+=d;
printf("%.2f",sum);
return sum;
}
int main(void) {
int t,n,i,j;float sum=0;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int r=0,s=0,a=0,b=0;
int x[n],y[n],p[n],q[n],min[n],max[n];
for(i=0;i<n;i++){
scanf("%d %d",&x[i],&y[i]);}
for(j=0;j<10001;j++){
for(i=0;i<n;i++){
if(j==x[i]){
p[r++]=x[i];q[s++]=y[i];
}
}}
for(i=0,j=i+1;i<n,j<n;i++,j++){
if(p[i]==p[j]){
if(q[i]>q[j]){min[a++]=p[i]; max[b++]=q[i];}
else{min[a++]=p[i]; max[b++]=q[j];}
}
else{min[a++]=p[i]; max[b++]=q[i];}
}
for(i=0;i<n;i++){
distance(min[i],max[i],min[i+1],max[i+1]);
}
}
}
As #YePhicK said, and I'll emphasize, learn to use a debugger.
Don't rely on guesswork or just eyeballs.
That said, I see something that, unless you really know what you're doing, is certain to break.
You have a loop using j as its index variable.
Then inside it, you have another loop that also uses j as an index variable.
for(j=0;j<10001;j++){ // <----- j used here
for(i=0;i<n;i++){
if(j==x[i]){
p[r++]=x[i];q[s++]=y[i];
}
}
for(i=0,j=i+1;i<n,j<n;i++,j++){ // <----- j used here
if(p[i]==p[j]){
if(q[i]>q[j]){min[a++]=p[i]; max[a++]=q[i];}
else{min[a++]=p[i]; max[a++]=q[j];}
}
else{min[a++]=p[i]; max[a++]=q[i];}
}
}
Also, you are using arrays called min and max.
There are commonly accepted macros called min and max, so if you redefine those you run the risk of a name collision.
Also, in code like this
{
min[a++]=p[i];
max[a++]=q[i];
}
it looks like you are putting empty spaces into arrays min and max by incrementing a twice.
This line:
int x[n],y[n],p[n],q[n],min[n],max[n];
is not correct. In C/C++ you cannot declare plain arrays of a variable size (unlike, say, in Basic). The size of such an array must be known at compile time.
Possible solutions are:
Use dynamic memory (malloc()/free())
Use a statically allocated arrays with a set maximum size (and either run a risk of buffer overflow and memory corruption or make sure you use no-more-than the space you have allocated for)
Use std::vector<int>
for(i=0,j=i+1;i<n,j<n;i++,j++)
The above for() statement contains the following (nonsensical) conditional expression:
i<n,j<n
Change this to one of the following:
i<n || j<n
or:
i<n && j<n
Also, variable 'float sum=0;' in 'main()' is unused; and main() should include a 'return(0);', or similar, at the end.

Resources