How do I implement functions in the C language? - c

I'm have a really hard time completing some homework, and would appreciate if anyone could sent me on the right path.
Basically, I've been asked to define a function that counts the number of iterations that occurs until a number grows larger than 10 or some number (max). I've made the function like this:
#include <stdio.h>
int iteration(float x, int max){
int n;
float y;
for (n=0;y=0;n++) {
y=y+x;
if (y>=10,max) {
break;
}
}
return n;
}
First off I'm not even sure if the if statement is correct (I don't know if it's proper code to just put a comma for "or"). After that, I'd imagine the rest of the code is okay (clarification would be greatly appreciated!).
Once this was done, I made a header file (Count.h where this file was Count.c) with just:
#include <stdio.h>
int iteration(float x, int max);
And finally, I used this header in a different file, which was just the header and then the main function like:
int main () {
iteration (9.8, 5);
return 0;
}
Everything compiles fine (but not through the "make" command, when I use icc individually to create each object file, it works), but nothing gets outputted or executed.
If someone can let me know where I'm going wrong, I'd really appreciate it! Or if you could give me a hint, I'm sure I could figure it out. I'm getting stressed because this is just the first part of a long homework assignment, and I can't believe I can't even figure this simple stuff out!
Thanks in advance!

this isn't a great question, and I would normally just comment, but I find it harder to format comments... here is the problem, probably...
for (n=0;y=0;n++)
so in C = is the assignment operator, and == tests equality... so the resulting expression y=0 will always evaluate to false... so this for loop will never be entered (equivalent is while(0))
it looks like you don't actually care about that term, so you can either leave it blank or make it a true value... or just make it the exit criteria, so ....
assert (x>0.0); // otherwise the loop will never exit
for (int i = 1; ; i++) // more idiomatic to use i as a loop counter
{
y+=x;
if (y > max)
{
return i;
}
}
return 0; // already over max
so you need:
float y = 0;
get rid of n it isn't doing anything.
or alternately you may have meant something like...
for( n=0,y=0;;n++)
which is fine but a little weird and complicated

To clarify, did you include your header in your main .C file (i.e. #include "Count.h")?
Also, you have iteration return 'n', but do nothing with it. You must either assign the returned integer to a variable (answer = iteration (9.8, 5);) or output it (printf("%i", iteration (9.8, 5))).
As long as you've included your header, your program is most likely executing as expected, but with nothing done with the returned value, it just ends without outputting anything.

Related

Two test cases giving me a nightmare

This is a code designed to multiply a matrix by another while skipping any unnecessary multiplication (Ones where either of the multipliers is 0)
I'm required to submit it for a course but I keep getting told 2 cases of the 10 just don't go through, what am I doing wrong here? I mean I know that it looks hideous and it's far from ideal in efficiency but I've reached the point where I just wanna be done with this.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main ()
{
int anr, anc, bnr, bnc, i, j;
scanf("%d", &anr);
scanf("%d", &anc);
int a[anr][anc];
for (i=0; i<anr; i++)
{
for (j=0; j<anc; j++)
{
scanf("%d", &a[i][j]);
}
}
scanf("%d", &bnr);
scanf("%d", &bnc);
int b[bnr][bnc];
for (i=0; i<bnr; i++)
{
for (j=0; j<bnc; j++)
{
scanf("%d", &b[i][j]);
}
}
if (anc!=bnr)
{
return 0;
}
else
{
int k;
int out[anr][bnc];
for (i=0;i<anr;i++)
{
for (j=0;j<bnc;j++)
{
out[i][j]=0;
for (i=0;i<anr;i++)
{
for (j=0;j<bnc;j++)
{
out[i][j]=0;
for (k=0;k<bnr;k++)
{
if ((a[i][k]!=0) && (b[k][j]!=0))
{
out[i][j]=a[i][k]*b[k][j]+out[i][j];
}
}
}
}
}
}
for (i=0;i<anr;i++)
{
for (j=0;j<bnc;j++)
{
printf("%d ", out[i][j]);
}
printf("\n");
}
}
return 0;
}
It looks like you've made a copy/paste error somewhere along the line between writing the code and posting it here- you loop over i and j within a loop over the same variables! This is obviously an issue. Without knowing what the code you're actually running is, it's not possible to say much about the specifics, but there are a few things that will help you more generally.
Comment your code. I cannot stress this enough. It's important in any kind of programming but it becomes much, much more so in numerical algorithms. Don't rely on your memory- you will make mistakes and they will become invisible to you that way. Simply going through the code and commenting each operation would make it very obvious that you were looping over the indices twice and nested, but it's very easy to look at the same code for hours on end and miss mistakes because they become part of the scenery.
Secondly, separate the logic into as small of parts as you can. Rather than loop over the result's entries, initialize the output array to zero, then loop over the index for the inner product, move the initialization into its own loop. It's a very simple task to move it back into a single loop, but separating it until you ensure you have correct code is an easy way to isolate problems and ensure, for example, that you aren't initializing to zero at the wrong level of nesting, or after you've calculated some results.
Finally, check your work at each step. Verify that you're reading in the correct values for a, then do the same for b. Make sure that your output is initialized to zero. If those aren't correct and you're searching in the multiplication code for a problem, you'll never find the issue. Then find the test case or cases that fail- print out the inputs and your output. If the issue is obvious, great. If not, see if you can construct a simpler example that also fails and go from there.
The overarching theme here is simplifying and clarifying the code as much as possible. The less you have to keep track of in your head, the easier it is to find issues. If you later want to condense the code, it'll be easy to figure out where each piece goes and if you introduce a problem you'll know exactly how, because you're starting with correct code.

Understanding the reason behind a output

I am a beginner is Computer Science and I recently started learning the language C.
I was studying the for loop and in the book it was written that even if we replace the initialization;testing;incrementation statement of a for loop by any valid statement the compiler will not show any syntax error.
So now I run the following program:
#include<stdio.h>
int main()
{
int i;
int j;
for(i<4;j=5;j=0)
printf("%d",i);
return 0;
}
I have got the following output.
OUTPUT:
1616161616161616161616161616161616161616.........indefinitely
I understood why this is an indefinite loop but i am unable to understand why my PC is printing this specific output? Is there any way to understand in these above kind of programs what the system will provide us as output?
This is a case of undefined behaviour.
You have declared i so it has a memory address but haven't set the value so its value is just whatever was already in that memory address (in this case 16)
I'd guess if you ran the code multiple times (maybe with restarts between) the outputs would change.
Some more information on uninitialized variables and undefined behaviour: https://www.learncpp.com/cpp-tutorial/uninitialized-variables-and-undefined-behavior/
Looks like i was never initialized, and happens to contain 16, which the for loop is printing continuously. Note that printf does not add a new line automatically. Probably want to read the manual on how to use for.
To better understand what is going on, you can add additional debugging output to see what other variables are set to (don't forget the \n newline!) but really problem is the for loop doesn't seem right. Unless there's something going on with j that you aren't showing us, it really doesn't belong there at all.
You are defining the variable i but never initializing it, instead, you are defining the value for j but never using it.
On a for loop, first you initialize the control variable, if you haven't already done it. Then you specify the condition you use to know if you should run another iteration or not. And last but not least, change the value of the control variable so you won't have infinite loops.
An example:
#include <stdio.h>
int main()
{
// 1. we declare i as an integer starting from 1
// 2. we will keep iterating as long as i is smaller than 10
// 3. at the end of each iteration, we increment it's value by 1
for (int i = 1; i < 10; i++) {
printf("%d\n", i);
}
return 0;
}

Matrix not zero-filled on declaration

I was trying to debug my code in another function when I stumbled upon this "weird" behaviour.
#include <stdio.h>
#define MAX 20
int main(void) {
int matrix[MAX][MAX] = {{0}};
return 0;
}
If I set a breakpoint on the return 0; line and I look at the local variables with Code::Blocks the matrix is not entirely filled with zeros.
The first row is, but the rest of the array contains just random junk.
I know I can do a double for loop to initialize manually everything to zero, but wasn't the C standard supposed to fill this matrix to zero with the {{0}} initializer?
Maybe because it's been a long day and I'm tired, but I could've sworn I knew this.
I've tried to compile with the different standards (with the Code::Blocks bundled gcc compiler): -std=c89, -std=c99, std=c11 but it's the same.
Any ideas of what's wrong? Could you explain it to me?
EDIT:
I'm specifically asking about the {{0}} initializer.
I've always thought it would fill all columns and all rows to zero.
EDIT 2:
I'm bothered specifically with Code::Blocks and its bundled GCC. Other comments say the code works on different platforms. But why wouldn't it work for me? :/
Thanks.
I've figured it out.
Even without any optimization flag on the compiler, the debugger information was just wrong..
So I printed out the values with two for loops and it was initialized correctly, even if the debugger said otherwise (weird).
Thanks however for the comments
Your code should initialize it to zero. In fact, you can just do int matrix[MAX][MAX] = {};, and it will be initialized to 0. However, int matrix[MAX][MAX] = {{1}}; will only set matrix[0][0] to 1, and everything else to 0.
I suspect what you are observing with Code::Blocks is that the debugger (gdb?) is not quite showing you exactly where it is breaking in the code - either that or some other side-effect from the optimizer. To test that theory, add the following loop immediately after the initialization:
``` int i,j;
for (i = 0; i < MAX; i++)
for (j = 0; j < MAX; j++)
printf("matrix[%d][%d] = %d\n", i, j, matrix[i][j]);
```
and see if what it prints is consistent with the output of the debugger.
I am going to guess that what might be happening is that since you are not using matrix the optimizer might have decided to not initialize it. To verify, disassemble your main (disass main in gdb and see if the matrix is actually being initialized.

C loops-OK to change counter or condition within loop?

Several books show me how to correctly write for, while, and do loops.
Lots of online articles compare them to each other.
But I haven't found any place that tells me what not to do. For example, would it screw things up if I change the value of the counter or condition variable within the loop?
I would like an answer that is not machine dependent.
Yes you can change the counter within a loop and it can sometimes be very useful. For example in parsing command line arguments where there is an option flag followed by a value. An example of this is shown below:
Enter the following command:
program -f filename -o option -p another_option
Code:
#include <string.h>
int main(int argc, char** argv)
{
char *filename, *option, *another_option;
if(argc > 1){
for(int i=1; i<argc; i++){
if(strcmp(argv[i],"-f")==0){
filename = argv[++i];
} else if(strcmp(argv[i],"-o")==0){
option = argv[++i];
} else if(strcmp(argv[i],"-p")==0){
another_option = argv[++i];
} else {
printf("Option \"%s\" not recognized, skipping\n",argv[i]);
continue;
}
}
} /* end if argc > 1 */
return 0;
}
The example program automatically increments the counter to access the correct command line string. There are of course ways to incorporate counters etc., but they would only make the code more cumbersome in this case.
As others have pointed out, this is where many people write bugs and one must be careful when incrementing counters within loops, particularly when the loop is conditional upon the counter value.
It is not invalid to change a loop counter inside a loop in C.
However, it is probably confusing to future readers and that's a good reason not to do it.
It depends on what you mean by "screw things up".
If you know what you are doing, you can change counter. The language has no restrictions on this.
Changing the counter variable in the loop is allowed, but be careful to know what you are doing to not create infinite loops by decreasing the variable when you shouldn't be.
Some algorithms actually benefit from this, but of course if you do this it makes your code less readable so make sure you comment what you are doing also.
Yes, you can change the counter and condition variables. They will just be evaluated with the next iteration of the loop.
Definiteley you can.But be careful not to make the loop disorder. Alter a conter in the loop happens a lot in do...while and while.
do{
counter++;
some expressions;
}
while(counter < SOMEVALUE);
Yes, in C/C++/C# You can change the counter etc. in the loop.
Like many other techniques, as long as you know what do you do, it's fine.
For example, this code:
int i;
for (i=0;i<5;i++)
printf("%d\n",i--);
is an infinity loop, but this version of bubble sort:
int *arr,n;
//allocate memory, assign values, and store the length of the array in n
int i;
for (i=0;i<n-1;i++)
if (arr[i]>arr[i+1]) {
int temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
if (i) i-=2;
}
is fine. (It's not exactly bubble sort. Instead of using nested loops, I go back in the array after swapping members in it)
Be careful changing counter variable inside a loop, not all loops are the same, "while" loop behaves differently. see this example?
No, it is NOT an infinite loop (on some compilers). run it, and see...
i=5;
while (i--)
{
i=100;
printf("%d \n",i)
}
We can change the counter value inside the loop but the final counter value wont be reflected as the for loop wont override the counter value.
here is the example in QTP VB script.
iLast = 4
For i= 1 to iLast
iLast=2
Next
Here the for loop should execute only for 2 times as iLast value is updated to 2 inside the loop but it is executing for 4 times.

Is there a syntactic error that I'm overlooking in this loop

Hey guys could you please spot the semantic error that's in the code below, it seems OK to me but my instructor claims that there still is an "syntactic" error.
This is a simple program that prints a simple series starting from 256.
The series depends on the value of the variable a which is 256 in this case.
Hence in this case the series looks like 256,16,4,2,1. */
#include <stdio.h>
#include <math.h>
int main()
{
int a = 256;
int square_root_a;
printf("%d\n", a);
repeat:
square_root_a = sqrt(a);
if (square_root_a >= 2)
{
printf("%d\n", square_root_a);
a = square_root_a;
goto repeat;
}else{
printf("%d\n", 1);
} return 0;
}
You declare a as an integer, which will round the result of sqrt() to the nearest integer.
I guess you're supposed to use double.
Well, if it's not about the goto, or the int-ness of the variables, then my guess is your teacher means something subtle, like the printfs in both branches of the if. They have exactly the same purpose! Why write two statements that do the same, if it's possible to use only one? Just move the first one to above the if, and delete the second one.

Resources