Unable to print the array values in C - c

It's just a simple C program to display the array elements taken from the user but idk why am getting the garbage values when trying to print the array... if anyone could help i would really appreciate that... thanks!!
#include <stdio.h>
#include <stdlib.h>
double *array_dou;
double* initializeDoubles(int *maxdouble)
{
printf("Enter the max. double value the program should support: ");
scanf("%d",maxdouble);
array_dou = (double *) malloc((*maxdouble)*sizeof(double));
if(array_dou == NULL)
{
printf("Error! memory not allocated.");
exit(-1);
}
return array_dou;
}
int enterDouble(double *doubles,int dcount,int maxdouble)
{
for(dcount=0; dcount<maxdouble; dcount++)
{
printf("Please enter a double value: ");
scanf("%f",&doubles[dcount]);
}
return dcount;
}
int main()
{
int maxdouble;
int dcount=0;
double *doubles;
doubles = initializeDoubles(&maxdouble);
dcount = enterDouble(doubles,dcount,maxdouble);
printf("\nDouble array\n");
for(int j=0;j<dcount;j++)
{
printf("%lf ",doubles[j]);
}
return 0;
}

Because you are calling enterDouble only once and it reads only one value. Besides you are accessing the memory out of bounds. You allocated dcount number of elements, so you can access the memory only through the indices 0 to dcount - 1, yet you are passing dcount to enterDouble, thus you are trying to write at index dcount (one past the limit).
All other entries are uninitialized, so there you have two reasons why you see "garbage": the undefined behaviour of accessing memory out of bounds and the fact that you haven't initialized any of the doubles.
What you need to do is call enterDouble for all indices:
for(int j = 0; j < dcount; ++i)
enterDouble(doubles, j);
And the dcount++; in enterDouble makes to me no sense, the caller knows which index it it passing, no need to returns the same index + 1.
Also see do not cast malloc and you are not freeing the memory you've
allocated.
Also the proper conversion specifier for reading doubles with scanf is %lf, not %f.
man scanf
...
l Indicates either that the conversion will be one of d, i, o, u, x, X, or n and the next pointer is a pointer to a long int or
unsigned long in (rather than int), or that the conversion will be one of e, f, or g and the next pointer is a pointer to
double (rather than float).
...
f Matches an optionally signed floating-point number; the next pointer must be a pointer to float.

Related

Determinant of the matrix — recursive function

I wrote a program which returns a determinant of a matrix. I have a problem, actually; it always returns the "0" value. I notice that my determinant always stays as 0 even though I add numbers to it.
I wrote an English translation in the comments to understand my program better. I use a method in which we select one number and then crossed the element from the column and line of the selected number and then calculate the determinant of the uncrossed elements.
#include<stdio.h>
#include<stdlib.h>
float wznmacierz(float*macierz, int rozmiar)/*"macierz" means a matrix and "rozmiar" is a size of matrix */
{
if (rozmiar == 1)
return *macierz;
float *podmacierz = malloc((rozmiar-1)*(rozmiar-1)*sizeof(float)); // making a second matrix for uncrossed elements.
int wyznacznik = 0; // wyznacznik is the determinant of matrix
for(int element_S = 0; element_S <rozmiar; element_S++) //element s is a number from first line
{
for (int w = 1 ; w < rozmiar; w++ ) //line of checking element
{
for(int kolumna = 0; kolumna < rozmiar; kolumna++)//column of chcecking element
{
if(kolumna == element_S)
continue;
*podmacierz = macierz[(rozmiar*w)+(kolumna)];
podmacierz++;
}
}
wyznacznik += macierz[element_S]*( element_S % 2 ? -1: 1)* wznmacierz(podmacierz, rozmiar-1);
}
return wyznacznik;
}
void main()
{
float a[2][2]={{1,3},{9,8}};
printf("%d", wznmacierz(a,2));
}
Change void main to int main, because main returns an int.
In printf("%d", wznmacierz(a,2)); , change %d to %g, because %d is for formatting an int, but wznmacierz returns a float. %g will format a float. Also add \n after %g to complete the line being output.
In printf("%d", wznmacierz(a,2));, change a to *a because wzmacierz expects a pointer to a float, not a pointer to an array of float. This is a kludge to get your program “working” quickly; see Notes below.
You cannot use podmacierz both to hold the start address of the allocated array and to increment to places within the array. Inside the loop on element_S, put float *p = podmacierz; to make a second pointer, and change the uses of podmacierz inside that loop to p.
Before returning from the function, use free(podmacierz); to release the allocated space.
Notes
In main, a is declared as float a[2][2]. This makes it an array of 2 arrays of 2 float. In the call wznmacierz(a,2), a is automatically converted to a pointer to its first element. That produces a pointer to an array of 2 float. However, wznmacierz is declared with a parameter float*macierz, which is a pointer to a float.
One way to fix this is to pass *a. Once a is converted to a pointer to its first element, a pointer to an array of float, then applying * produces the thing that pointer points to, an array of float. Then that array of float is automatically converted to a pointer to its first element, producing a pointer to a float. You could also write wznmacierz(&a[0][0], 2).
This produces a pointer of the correct type for wznmacierz, which then access the array by calculating element locations, using macierz[(rozmiar*w)+(kolumna)]. This nominally calculates correct addresses for the array elements, since arrays are laid out in memory contiguously, but it is bad style unless necessary, and some people might consider it not to conform to the C standard in a pedantic sense.
One fix would be to define a in main as float a[2*2] = {1, 3, 9, 8};. Then the matrix is implemented as single flat array of float everywhere it is used.
Another fix would be to upgrade wznmarcierz to use two-dimensional arrays. A number of changes are needed to do this. I have not tested them, but I think they are at least:
Change wznmacierz(a,2) to wznmacierz(2, a).
Change the declaration of wznmacierz to float wznmacierz(int rozmiar, float macierz[rozmiar][rozmiar]).
Change the use of macierz inside the function from macierz[(rozmiar*w)+(kolumna)] to macierz[w][kolumna].
Change float *podmacierz = malloc((rozmiar-1)*(rozmiar-1)*sizeof(float)); to float (*podmacierz)[rozmiar-1] = malloc((rozmiar-1) * sizeof *podmacierz);.
Remove the float *p = podmaciarz; that I told you to insert above.
Inside the loop using w, insert float *p = podmacierz[w];.
Change macierz[element_S] to macierz[0][element_S].
Change wznmacierz(podmacierz, rozmiar-1) to wznmacierz(rozmiar-1, podmacierz).

There is an C function with pointers and a char return, what only returns the char value and 0 to the pointers

The objective here is to print the student's average grade as a letter (A for Aprooved, R for Reprooved, or F for Miss, or Falta, in Portuguese), with the average grade value itself, and the student's total presence in classes, using pointers to avg and misses. But after compilation, only the char return value is printed, with 0 on the others.
I tried to print the stored values in the pointers *avg and *presence, but the program takes the student grade values and present values before crashing.
#include <stdio.h>
char situation(float n1,float n2,float n3,int misses, int classes, float
*avg, float *presence);
int main()
{
float *avg, *presence, vet[3];
int f, a, x;
printf("Write the value of your notes \n");
for(x=0;x<=2;x++)
{
printf("Note %d:",x+1);
scanf("%f",&vet[x]);
}
printf("Misses: ");
scanf("%d",&f);
printf("Given: ");
scanf("%d",&a);
char outcome=situation(vet[0], vet[1], vet[2], f, a, &avg, &presence);
printf("With an average of %f and presence of %f percent, your situation is %c",avg,presence,outcome);
return 0;
}
char situation(float n1,float n2,float n3,int misses, int classes, float
*avg, float *presence)
{
char result;
*presence=((classes-misses)/classes)*100;
*avg=(n1+n2+n3)/3;
if(*presence>=0 && *presence<75)
{
result='F';
}
if(*presence>=75 && *presence <=100)
{
if(*avg>=0 && *avg<6);
{
result='R';
}
if(*avg>=6 && *avg<=10)
{
result='A';
}
if(*avg<0 || *avg>10)
{
result='x';
}
}
if(*presence<0 || *presence>100)
{
result='x';
}
return result;
}
I expected the student's total presence and the average grade as a value and letter (A, R, or F), printed on the terminal to the user, but it only returned the char result value.
Your code has one main problem:
float *avg,*presence,
When you a calling
char outcome=situation(vet[0],vet[1],vet[2],f,a,&avg,&presence);
You are passing the address to the pointer you just declared. By changing the value in the function outcome, you are changing the address that avg and presence are pointing to, not the value of the variable.
Try changing to
float avg,presence
This way, when you change the value (using the * operator) you will change the actual variable value.
You may find this that presence still be showing as 0 on the printf. This is because how C works with types in arithmetics operations. Your division has only ints on it, so the result will be a int. Given the result will always be >= 1, the result will be rounded to the int value, which is 0.
To fix that just put a float value in the division and the result will be a float.
Something like:
*presence=((classes-misses)/(classes*1.0))*100;
avg is a float pointer, you are sending it by pointer (&avg) so your function needs to be (int n1,....,float **avg,...)
Try to send avg without the &.
Give him a value before (it is better)
The compiler warning pointed you directly to the problem. You should examine the warning and come to understand what it means and why it was issued.
Your error is here:
float *avg,*presence
These should be declared as float, not float *.

function declaration and call and definition in c

Why is this code not running after printing of array if I take value of n>=9?
#include <stdio.h>
#include <math.h>
float mean_function(float array[],int n);
int main() {
int i,n;
float array[n],mean,sum=0,s2,summation,deno,C[i],elements;
printf("Enter No of Elements\n");
scanf("%d",&n);
printf("Enter Elements\n");
for(i=0;i<n;i++){
scanf("%f",&array[i]);
printf("%f",array[i]);
}
printf("sample variance(s2) : (sum((x-mean)*(x-mean)))/(n-1) /n");
printf("population variance(sigma2) : (sum((x-u)*(x-u))/n");
mean_function(array,n);
for(i=0;i<n;i++) {
deno=((array[i]-mean)*(array[i]-mean));
C[i]=deno;
summation=summation+C[i];
}
s2=((summation)/(n-1));
printf("s2=%f \n",s2);
}
float mean_function(float array[],int n) {
int i;
float sum=0,mean;
for(i=0;i<n;i++){ sum=sum+array[i]; }
mean=(sum/n);
return mean;
}
Why is this code not running after printing of array if I take value
of n>=9?
Some thoughts about your code (and about building programs in steps):
Arrays in C don't change in size once defined. VLAs are out for a variety of reasons. malloc() is in.
Use double, unless there is a specific reason to use floats.
Define and initialize one variable per line. Uninit vars can only result in an error as mentioned by #Jens.
Function declarations at the top (which you have done)
During development, there is no need to complicate things with a scanf (at least initially). It only adds an unwarranted layer of complexity. If you are testing statistical functions (mean, variance), put numbers in a pre-defined static array and verify functionality first.
C[i] as been declared with uninitialized i.
For this initial phase of building this program, I include a basic program.
I am not a fan of zero space between tokens (but ignore that)
Consider calling your array something other than 'array'.
Calculating the size of the samples array allows you to change the number of elements without changing anything else in code; which adds another layer of complexity to an already difficult phase.
#include <stdio.h>
#include <math.h>
double sample_mean(double* p, int n);
int main()
{
double samples[] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 16.5, 2.3};
double mean = 0.0;
int size_samples = sizeof samples/sizeof(double);
printf("size_samples = %d\n", size_samples);
mean = sample_mean(samples, size_samples);
printf("Mean = %.2lf", mean);
}
// -------------------------------
double sample_mean(double* p, int n)
{
double mean = 0.0;
double total = 0.0;
for(int i = 0; i < n; i++)
total += *p++;
mean = total/n;
return mean;
}
Once this functionality is present (saved), you can start working on other stat functions. This way you can work step by step to get closer to the desired outcome.
Next up you can define sample_variance(double* p, int n) and work on that knowing that additional(new errors) are not coming from your code written so far.
Output:
size_samples = 8
Mean = 5.24
I hope it helps.
The code is likely not running because array[n] is declared with an uninitialized n. At the time you read n with scanf(), the array does not automatically "grow into the right size". You should either declare array big enough, or if you really want it to be user-defined, use malloc to allocate it (read the comp.lang.c FAQ) and all Stackoverflow questions tagged array...)
In addition, the scanf at some point fails. Note that when you enter numbers, you also have the "Enter" as a newline ('\n') in the input stream. You never read the newline so the next scanf fails.
This becomes obvious when you actually check the return value from scanf with code like this:
if (scanf("%f", &array[i]) == 1) {
/* successfully converted 1 item */
}
else {
/* scanf failed */
}
Usually what you want is to skip whitespace in the input. You do this by placing a space in the scanf format. Note that a single space tells scanf to skip any amount of white-space.
if (scanf(" %f", &array[i]) == 1) {

Solve segmentation fault error in C

I am trying to store the sum 1/k^2 in an array using this code:
int main()
{
int i,n, e;
double terms[n];
double x, y;
printf(" Introduce n\n");
scanf("%d", &n);
y=1;
i=0;
while(e<n)
{
x=1/((y)*(y));
printf("x is %.16lf\n",x);
terms[i]=x;
printf("terms is %.16lf\n", terms[i]);
y++;
i++;
e++;
}
}
And I get the "segmentation fault" error. Why is this happening? How can I avoid it?
I am programming in C
n is garbage in double terms[n]; that causes undefined behaviour. Enable compiler warning by compiling with gcc -Wall and observe. Never ignore warnings.
Initialize n before declaring terms[n] OR
printf(" Introduce n\n");
scanf("%d", &n);
double terms[n];
Also e is uninitialized, initialize it.
e = 0 ;
while (e < n){
/* code */
}
When declaring an array with n elements (double terms[n];), the allocation of said array is done in the compilation stage. Because you left your n variable un-initialized, it has indeterminate value (random from the user perspective), so you don't know what is the size of said array.
Scanning an int into n later, does not help at all as it is done in the run-time (and also, it is done AFTER the array declaration. It could have worked if you have used malloc for the allocation AFTER the scanf).
Anyway, you currently have an array with "random" size, and accessing it is Undefined Behavior -> segfault
The crash comes from undefined size of the terms[n] array. You are crossing array memory boundaries.
A few variables are not initialized:
double terms[n]; // n is not initialized
while (e<n){ // e is not initialized
You have many choices to properly build terms array (marked in the code as well):
1) Decide upfront on the specific size of the array. (This is not flexible approach!)
2) Allocate array dynamically when you read n.
3) Declare terms[n] after reading n.
Test program:
#include <stdio.h>
#include <stdlib.h>
int main(){
int i;
int n;
int e = 0;
// 1. One of the 3 choices - thus is a rigid one
// double terms[TERMS_SIZE]; // make TERMS_SIZE big enough, read n has to be less than TERMS_SIZE
double x, y;
printf(" Introduce n\n");
scanf("%d", &n);
// 2.
// double *terms = malloc ( n* sizeof sizeof(double));
// or
// 3.
double terms[n];
y=1;
i=0;
while (e<n){
x=1/((y)*(y));
printf("x is %.16lf\n",x);
terms[i]=x;
printf("terms is %.16lf\n",terms[i]);
y++;
i++;
e++;
}
// If 2. used free the memory
// free(terms);
return 0;
}
Output:
4
Introduce n
x is 1.0000000000000000
terms is 1.0000000000000000
x is 0.2500000000000000
terms is 0.2500000000000000
x is 0.1111111111111111
terms is 0.1111111111111111
x is 0.0625000000000000
terms is 0.0625000000000000

Initialize a double array with int values in C

I'm learning some c now, and must do an exercise for the university. I need an double array which should be filld with int values. So I've this.
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[] ) {
int size=0, i=0;
printf("Enter size of array: ");
scanf("%d", &size);
double* field = malloc(size * sizeof(double));
double value;
for(i=0; i<size; i++) {
field[i] = i;;
}
for(i=0; i<size; i++) {
printf("Field%i: %d\n",i, field[i]);
}
free(field);
return 0;
}
But, when I execute it all values are set to 0.
Enter size of array: 10
Field0: 0
Field1: 0
Field2: 0
Field3: 0
Field4: 0
Field5: 0
Field6: 0
Field7: 0
Field8: 0
Field9: 0
printf's %d stands for decimal integer, not double.
So this line:
printf("Field%i: %d\n",i, field[i]);
should be:
printf("Field%i: %f\n",i, field[i]);
Using the wrong format specifier is undefined behavior which you had earlier.
From standard
If any argument is not the correct type for the corresponding
conversion specification, the behavior is undefined.
Also check the return value of malloc. It let's you know whether the allocation failed (returns NULL) or not.
A bit more insight from David C. Rankin's comment
The %d format
specifier was looking for 4-bytes (sizeof int bytes) in memory
ordered based on the endianess of your machine. When you provided an
8-byte (sizeof double) value comprised of a sign-bit, normalized
exponent and mantissa, it had no idea what to do with it.
Well here in printf we can use %f instead of %lf also which has added benefit of compatibility with pre-C99 versions and also it is shorter. (chux pointed this).
I don't think whether malloc function allocated the memory for the array. Check the syntax of malloc and also the return type.

Resources