An Address is Printed Instead of the Expected Value - c

I am trying to write a simple program. I am a begineer and i am not getting a value to total. When i am trying to print . I am getting a address as output . Can anyone explain me what is the mistake and correct my program .
#include<stdio.h>
void main()
{
int first,second,total;
printf("enter the value for the first");
scanf("%d",&first);
printf("enter the value for the second");
scanf("%d",&second);
total=power(first,second);
printf("The value for power is %d",power);
}
int power(int doom1,int doom2)
{
int temp=doom1;
int i;
for(i=1;i<=doom2;i++)
{
temp=temp*doom1;
}
return temp;
}

You are printing the wrong variable:
total=power(first,second); //here you are getting return value in variable total
printf("The value for power is %d",power); // power is the function name not variable
Replace this line with:
printf("The value for power is %d",total); // you need to print `total`
Also you have to declare your function prototype before main():
int power(int ,int);
and you should use int main():
int main()
{
// your code
return 0;
}

In addition to passing total to printf instead of power, as you are just starting, make a point to always give your variables an initial value (initialize them). This prevents an attempt to read from uninitialized space which is the bane of new C programmers. (it will save you a lot of headaches). Attempting to read from an uninitialized variable is Undefined Behavior. That can result in anything from slipping by unnoticed, to causing your program to crash. It is to be avoided.
Also, as I explained in the comment, in C, the function main() is type int and it returns a value to its caller (usually the shell, or another program). When using main without arguments, the proper form is:
int main (void)
When accepting arguments, the proper form is:
int main (int argc, char **argv)
In either case, it should return a positive value upon completion. A return 0; at the end is all that is required. exit (0); is another function you can use to return a value. You will also see the form of main with arguments written as:
int main (int argc, char *argv[])
The first and second forms are the practical equivalents of each other, the first recognizing that an array passed to a function in C will decay to a pointer. But for now, just understand that they are equivalent.
You also have an error in your my_power calculation. int temp = doom1; should be int temp = 1; Your calculation was returning a value twice the actual product.
Your style of syntax is up to you, but I would suggest that expanding your syntax a little by using discretionary spaces and lines will make your code much more readable and make finding errors a bit easier. Here is an example regarding all of these points:
#include <stdio.h>
int my_power (int doom1, int doom2);
int main (void)
{
int first = 0; /* Always initialize your variable to prevent */
int second = 0; /* an inadvertant read from an unitialized */
int total = 0; /* value which is Undefined Behavior (bad). */
printf ("\n enter the value for the first : ");
scanf ("%d",&first);
printf (" enter the value for the second: ");
scanf ("%d",&second);
total = my_power (first,second);
printf ("\n The value for my_power is: %d\n\n", total);
return 0;
}
int my_power (int doom1, int doom2)
{
int temp = 1;
int i = 0;
for (i = 1; i <= doom2; i++)
temp = doom1 * temp;
return temp;
}
Output
$ ./bin/simple_function
enter the value for the first : 2
enter the value for the second: 7
The value for my_power is: 128

you are trying to print "power" without parameter
printf("The value for power is %d",power);
you should do
printf("The value for power is %d",total);
or
printf("The value for power is %d",power(first,second));

Related

Totally unexpected output when trying to compute the average using arrays

I am trying to compute the average after reading in the data from a text file of int type.The program compiles fine. clang -std=gnu11 -Weverything -g3 -pedantic -g3 -O3 -lm average_weight_of_elephant_seals.c -o average_weight_of_elephant_seals
Suppose I want to compute the average weight of 2000 seals,the expected output is 6838.848152 but I get 1710.566467.I have no idea how to make sense of GDB yet.
Could someone please point out where have I have gone wrong?
/* The following program demonstrates the usage of fscan to read in a set of integer data into a file and then computes the sum followed by the average.
* The computation shall be encapsulated in a function and then be called in the main routine
*/
#include <stdio.h>
#define MAXSIZE 5000 /* Macro definition to pre-define the size of the array */
double average_weight(int count, int weights_array[]);
int main(void)
{
int number_of_seals;
int weights_array[MAXSIZE];
printf("Enter the number of seals: \n");
scanf("%i", &number_of_seals);
printf("Their average weight is %lf\n", average_weight(number_of_seals, &weights_array[number_of_seals]));
return 0;
}
double average_weight(int count, int weights_array[])
{
/* Variable declaration and initialization
* Note the use of the FILE data type */
int weight;
int sum = 0;
FILE *elephant_seal_data = fopen("elephant_seal_data.txt", "r");
if (elephant_seal_data == NULL)
{
return -1;
}
/* FEOF function to determine if EOF has been reached or not */
while (!feof(elephant_seal_data))
{
fscanf(elephant_seal_data, "%i", &weight);
weights_array[count++] = weight;
sum += weight;
count++;
}
double average_weight = (double)sum / (double)count;
fclose(elephant_seal_data);
return average_weight;
}
printf("Their average weight is %lf\n", average_weight(number_of_seals, &weights_array[number_of_seals]));
The code passes a pointer to a position into the array for no apparent reason, and does not check if number_of_seals * 2 is less than MAXSIZE so may overflow the array. But the array isn't needed for this calculation anyway.
weights_array[count++] = weight;
sum += weight;
count++;
The code is writing to the array not reading it. The array is not needed for this calculation.
The code increments count twice, so the average will be out by a factor of two, and alternate locations in the array will have undefined values in them.
There are 2 stupid mistakes in your code, a nastier one, and a risk.
First the stupid ones:
You pass count to the function and increment that value twice per each value in the file. If the initialy given value was correct, you end with a count 3 times too big. You should not pass count to the function but compute it there.
You use a wrong syntax to pass an array: you are expected to pass a pointer to its first element.
Now the nasty one: while Why is “while ( !feof (file) )” always wrong? is indeed a FAQ, is is still a common thing in beginners code...
feof only returns true after a read operation returned an error. Let us examine what happens for the last value. It is read and correctly processed once. feof still returns false (no error so far) so your code re-enters the loop. scanf reaches the end of file and returns 0 (what your code ignores) but does not change the values => the last value will be processed twice. Never ever use while (!feof(...
And finally the risk.
You are summing value into an integer. Even if the average will easily fit there, if you had larger value and a very high number of them, you could get an integer overflow. The recommended way it to sum into a larger type (double?) and if possible use a guess to limit the cumulative error: average(qty-guess) + guess is indeed average(quantity), but the computed sum can be much lower, limiting the cumulative error when using floating point values or preventing overflow when using integer ones. From the number of seals and the expected average there should be no problem here so a guess is useless, but remember that for a different use case...
Last but not least, main is expected to be declared as int main() if you do not care for additional parameters but never int main(void)
Code could become:
/* The following program demonstrates the usage of fscan to read in a set of integer data into a file and then computes the sum followed by the average.
* The computation shall be encapsulated in a function and then be called in the main routine
*/
#include <stdio.h>
#define MAXSIZE 5000 /* Macro definition to pre-define the size of the array */
double average_weight(int* count, int weights_array[]);
int main()
{
int number_of_seals;
int weights_array[MAXSIZE];
double weight = average_weight(&number_of_seals, weights_array);
printf("Their number is %d and their average weight is %lf\n", number_of_seals, weight);
return 0;
}
double average_weight(int* count, int weights_array[])
{
/* Variable declaration and initialization
* Note the use of the FILE data type */
int weight;
int sum = 0;
FILE* elephant_seal_data = fopen("elephant_seal_data.txt", "r");
if (elephant_seal_data == NULL)
{
return -1;
}
*count = 0;
/* FEOF function to determine if EOF has been reached or not */
for(int i=0; i<MAXSIZE; i++) // never process more than the array size
{
if (1 != fscanf(elephant_seal_data, "%i", &weight)) {
break; // immediately stop at end of file
}
weights_array[(* count)++] = weight;
sum += weight;
}
double average_weight = (double)sum / (double)*count;
fclose(elephant_seal_data);
return average_weight;
}
I have kept your general program structure unchanged, but IMHO, you are expected to first read the data into an array, and then pass that populated array along with its count to an average function. Just split your current function into 2 steps.
You have sent the number of counts to use in the array which is great, since the function does not know the length of the weights_array. But you are not using it properly.
I'd suggest you to:
Use count to limit the number of loops based on how many data you want.
Do not change/reassign the value of count. Since this number is crucial to calculate the average. Create some other variable to do the task.
So here is how I slightly modified your code to bring those changes. I assumed the format of elephant_seal_data.txt as space separated integer values.
#include <stdio.h>
#define MAXSIZE 5000 /* Macro definition to pre-define the size of the array */
double average_weight(int count, int weights_array[]);
int main(void)
{
int number_of_seals;
int weights_array[MAXSIZE];
printf("Enter the number of seals: \n");
scanf("%i", &number_of_seals);
printf("Their average weight is %lf\n", average_weight(number_of_seals, &weights_array[number_of_seals]));
return 0;
}
double average_weight(int count, int weights_array[])
{
/* Variable declaration and initialization
* Note the use of the FILE data type */
int weight;
int sum = 0;
int i = 0;
FILE *elephant_seal_data = fopen("elephant_seal_data.txt", "r");
if (elephant_seal_data == NULL)
{
return -1;
}
/* FEOF function to determine if EOF has been reached or not */
while (i<count)
{
fscanf(elephant_seal_data, "%d", &weight);
weights_array[i++] = weight;
if (feof(elephant_seal_data)) break;
sum += weight;
}
double average_weight = (double)sum / (double)count;
fclose(elephant_seal_data);
return average_weight;
}
Edit:
I have used the elephant_seals_data.txt to simulate these in Google Colab for you. Try running the first cell there.
Google Colab Link

Basic question about how this C code is working

#include <stdio.h>
#include <cs50.h>
int get_pos_int(void);
int main(void) {
int i = get_pos_int();
printf("You entered the positive Integer of %i\n", i);
}
int get_pos_int(void) {
int n;
do {
n = get_int("Insert a positive Integer: ");
}
while(n < 1);
return n;
}
So of course this is just a simple program to test for if a number entered is a number above 0. Out of interest I decided to make this small change to see if it was semantically still correct.
int main(void) {
get_pos_int();
printf("You entered the positive Integer of %i\n", get_pos_int());
}
When running the program with this change, if I input the number '1' it returns me back to the prompt to type an integer, then if I type 1 again it returns 'You entered the positive Integer of 1'
I was just wondering if you could explain what the behaviour is causing this, I like to know why things are working the way they are and it interested me how removing the function being stored in a variable made it behave this way.
Based on your description of what happens, I'm assuming you meant get_pos_int() in your printf.
int i = get_pos_int() stores the return value of the function, not the function itself. So when you made your change, you call the function but discard the value it returns. The function then gets called again in your printf statement. The function being called twice is why you have to enter 1 twice.

Decimal integer to binary in C

Please give me some feedback on how to make my code better or more efficient. It should convert a decimal integer to binary.
#include <stdio.h>
binarydigits(int div, int dis)
{
int numit;
numit=0;
do
{
++numit;
div /= dis;
}
while (div!=1);
++numit;
return numit;
}
main()
{
int x, nb, i;
printf("\n Input an decimal integer number to be converted: ");
scanf("%d", &x);
fflush(stdin);
if (x==0 || x==1)
{
printf("\n\n %d in binary : %d", x, x);
}
else
{
printf("\n\n %d in binary : ", x);
nb = binarydigits(x, 2);
// the function 'binarydigits' returns how many binary digits are needed to represent 'x'
int remind[nb];
// an array of 'nb' elements is declared. Each element of this array will hold a binary digit
for(i=(nb-1) ; i>=0 ; --i, x/=2)
{
remind[i] = x%2;
}
//this 'for' structure saves the remainder of 'x/2' (x%2) in an element of the 'remind[nb]' array
for (i=nb ; i>0 ; --i)
{
printf("%d", remind[nb-i]);
}
//this 'for' structure prints the elements of the 'remind[nb]' array in increasing order
}
getch();
return 0;
}
Any tips on how to make this better would be nice.
Firstly, binarydigits should have a return type int. This is because you return an integer variable numit at the end of this function. Change your function header to:
int binarydigits(int div, int dis)
Secondly, the main() function needs to have a return type int by definition in C, and C++ for that matter. Without it, your compiler will produce a warning, something similar to:
main.c:18:1: warning: return type defaults to 'int' [-Wimplicit-int]
main()
^~~~
Here is a snippet from the the C11 standard (ISO/IEC 9899:2011) on the definition of the main() function:
The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters: - Return Type of main()
int main(void) { /* ... */ }
Thirdly, you should remove fflush(stdin) because using the fflush() for stdint is undefined behavior as it is not a part of standard C. From C11 7.21.5.2, fflush works only with output/update stream, not input stream:
If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined. - fflush(stdin)
How to make my code better or more efficient?
My advice to you is to stop trying to learn C by trial-and-error method. You should obtain a good book and study it first. It is impossible to create a fast and efficient C program without mastering pointers, bitwise operators and memory manipulations.
Simply, to make your code fast, you should completelly delete your code (I am not going to list all of your bad-practice things here) and start understanding my example:
int main(void){
char *s = (char*)malloc(33);
char *t = s;
int a;
s += 33;
*s = 0;
printf("Enter a number: ");
scanf("%d", &a);
printf("That number in binary: ");
while(a){
*(--s) = a & 1 ? '1' : '0';
a >>= 1;
}
printf("%s\n", s);
free(t);
return 0;
}
Explanation: we have pointer (if you don't know pointers, well you should probably first learn them) s which points to the end of a string. While number from input (number a) is nonzero, we put its last binary digit in the string, decrease pointer and divide a integrally by 2 (this is a >>= 1 instruction). When a is 0, just print the string.

Summing an Array of Numbers but Receiving Error when Run [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to sum an array of numbers. The array has a length determined by an input and then the user gives the array. There were no compilation errors and I am able to run other programs. On the immediate start of running the program I am given a message that program has stopped working and that windows is searching for solution.
#include <stdio.h>
int main()
{
int sum, length, count;
int array[length];
sum=0;
scanf("%d",&length);
scanf("%d",&sum);
for(count=0; count<length-1; count++)
{
sum = sum + array[count];
}
printf("%d", sum);
return 0;
}
When you declare your array it depends on length but you ask the user for length after.
A solution could be to ask the user for length (scanf("%d",&length);) before declaring your actual array (int array[length];).
you should move int array[length] to after scanf("%d", &length). But it is not allowed in C to declare variables after the first non-declaration (it is however possible if you compile this program as C++).
In fact, in standard C you can't have a non-const length definition for an array variable. gcc on the other hand for example allows this nevertheless.
In your case, the problem is that length has an undefined value at the declaration of int array[length];. If you are lucky, your data segment has been initialized to zero (there is no guarantee for that) but otherwise, it may be any value, including a value which leads the program to exceed your physical memory.
A more standard way of doing this is:
int *array = NULL;
scanf("%d",&length);
...
array = (int*) malloc(sizeof(int) * length);
...
free(array);
By the way, even after fixing that, you will most likely get random numbers because you never actually assign the contents of the elements of array.
Local variable are initialized to 0. Hence value of length is 0. So you array is of length. You are then reading length, say 10, from stdin and expect the array to be of length 10. This can't be. Since this is a stack variable, the size is determined in time of pre-processing and not in run time. If you want to define the array length in run time then use malloc.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int sum, length, count;
int *array;
sum=0;
scanf("%d", &length);
scanf("%d",&sum);
array = (int *)malloc(sizeof(int) * length);
if (array == NULL) return 0;
memset(array, length, 0);
for(count=0; count<length-1; count++)
{
sum = sum + array[count];
}
printf("%d", sum);
return 0;
}
Thanks.
first problem:
the length variable is being used to set the number of entries in the array[], before the variable length is set. Therefore, length will contain what ever trash happens to be on the stack when the program starts so the number of entries defined in array[] is an unknown.
This results in undefined behaviour and could lead to a seg fault event, depending on what was on the stack and what the user entered for length.
second problem:
The array array[] is never initialized so will contain what ever trash is on the stack at program startup. This means the value being printed could be anything. And the 'sum' could overflow, depending on the trash values in array[]
OP program lacks the part of data input, it's asking for sum instead of the values to sum, which is weird. The only inputs requested are also never checked (the return value of scanf must always be checked).
In C (at least C99 and optionally C11) Variable Length Arrays, like the one defined by int array[length], can be used, but the variable length here is used uninitialized and before it is even asked to the user.
Moreover, the loop where the sum is calculated stops before the last element of the array (not really a big deal in this case, considering that all those variables are uninitialized...).
A better way to perform this task could be this:
#include <stdio.h>
// helper function to read an integer from stdin
int read_int( int *value ) {
int ret = 0;
while ( (ret = scanf("%d", value)) != 1 ) {
if ( ret == EOF ) {
printf("Error: Unexpected end of input.\n");
break;
}
scanf("%*[^\n]"); // ignore the rest of the line
printf("Please, enter a number!\n");
}
return ret;
}
int main(void) {
int sum = 0,
length = 0,
count,
i;
printf("Please, enter the number of values you want to add: ");
if ( read_int(&length) == EOF )
return -1;
// Use a VLA to store the numbers
int array[length];
// input the values
for ( count = 0; count < length; ++count ) {
// please, note ^^^^^^^^ the range check
printf("Value n° %2d: ", count + 1);
if ( read_int(&array[count]) == EOF ) {
printf("Warning: You entered only %d values out of %d.\n",
count, length);
break;
}
// you can sum the values right here, without using an array...
}
// sum the values in the array
for ( i = 0; i < count; ++i ) {
// ^^^^^^^^^ sum only the inputted values
sum += array[i];
}
printf("The sum of the values is:\n%d\n", sum);
return 0;
}

How can i add numbers to an array using scan f

I want to add numbers to an array using scanf
What did i do wrong? it says expected an expression on the first bracket { in front of i inside the scanf...
void addScores(int a[],int *counter){
int i=0;
printf("please enter your score..");
scanf_s("%i", a[*c] = {i});
}//end add scores
I suggest:
void addScores(int *a, int count){
int i;
for(i = 0; i < count; i++) {
printf("please enter your score..");
scanf("%d", a+i);
}
}
Usage:
int main() {
int scores[6];
addScores(scores, 6);
}
a+i is not friendly to newcomer.
I suggest
scanf("%d", &a[i]);
Your code suggests that you expect that your array will be dynamically resized; but that's not what happens in C. You have to create an array of the right size upfront. Assuming that you allocated enough memory in your array for all the scores you might want to collect, the following would work:
#include <stdio.h>
int addScores(int *a, int *count) {
return scanf("%d", &a[(*count)++]);
}
int main(void) {
int scores[100];
int sCount = 0;
int sumScore = 0;
printf("enter scores followed by <return>. To finish, type Q\n");
while(addScores(scores, &sCount)>0 && sCount < 100);
printf("total number of scores entered: %d\n", --sCount);
while(sCount >= 0) sumScore += scores[sCount--];
printf("The total score is %d\n", sumScore);
}
A few things to note:
The function addScores doesn't keep track of the total count: that variable is kept in the main program
A simple mechanism for end-of-input: if a letter is entered, scanf will not find a number and return a value of 0
Simple prompts to tell the user what to do are always an essential part of any program - even a simple five-liner.
There are more compact ways of writing certain expressions in the above - but in my experience, clarity ALWAYS trumps cleverness - and the compiler will typically optimize out any apparent redundancy. Thus - don't be afraid of extra parentheses to make sure you will get what you intended.
If you do need to dynamically increase the size of your array, look at realloc. It can be used in conjunction with malloc to create arrays of variable size. But it won't work if your initial array is declared as in the above code snippet.
Testing for a return value (of addScores, and thus effectively of scanf) >0 rather than !=0 catches the case where someone types ctrl-D ("EOF") to terminate input. Thanks #chux for the suggestion!

Resources