I'm trying to pass an array to a function that sums up all the elements in the array, but I get a bad access error at the line sum+=a[i]; how can i fix this? Here is the code:
#import <Foundation/Foundation.h>
int sum(int*, int);
int main() {
#autoreleasepool {
int size = 0;
int a[size];
int x;
NSLog(#"Enter a size for the array ");
scanf("%i", &size);
NSLog(#"Enter %i numbers to populate the array ", size);
for (int i = 0; i < size; i++) {
scanf("%i", &a[i]);
}
x = sum(a, size);
NSLog(#"The sum of the array is %i ", x);
}
return 0;
}
int sum(int *a, int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += a[i];
}
return sum;
}
It is because your array is 0 in size. Writing / Reading from a[i] may / may not crash as it's behavior is undefined.
Instead of
int size = 0;
int a[size];
int x;
NSLog(#"Enter a size for the array ");
scanf("%i", &size);
you should do this instead:
int size = 0;
int *a;
int x;
NSLog(#"Enter a size for the array ");
scanf("%i", &size);
a = malloc(sizeof(int) * size);
By dynamically allocate the array a, your program should no longer crash.
And after we use malloc, we have to free it when we don't need it anymore. Put this before return 0;
free(a);
Hope this helps.
You've defined an array of size 0. Since an array is a block of memory, and in this case a block of "no" memory, you cannot store anything into it.
You can use malloc/free as indicated in #Owen's answer. C99 also added the ability to declare arrays on the stack (so-called VLA, Variable Length Arrays). This saves you using malloc/free but leaves you at risk of using up all your stack space. For values which you know for a fact will be constrained, a VLA might make sense:
int size;
NSLog(#"Enter a size for the array ");
scanf("%i", &size);
int arr[size];
....
Note that in C89/C90/ANSI you would not be able to do that, since the size of an array must be a compile-time constant.
Related
#include <stdio.h>
int main()
{
//Initialize array
int n; // n is use to decide the size of array
int x[n];
int y[n];
printf("enter the size of array:");
scanf("%d", &n);
if (n > 0)
{
for (int i = 0; i < n; i++)
{
printf("enter elements : \n");
scanf("%d", &x[i]);
}
}
printf("Array in reverse order: \n");
//Loop through the array in reverse order
for (int i = n - 1, j = 0; i >= 0; i--, j++)
{
y[j] = x[i];
printf("%d ", y[j]);
}
return 0;
}
In the above program, I have created a array whose size can be decided by the user. The user can also put elements in it.
After that I want to reverse this array and store the data in another array. But I get this error again and again. I am using CodeBlocks with the GCC compiler.
When the x and y arrays are created, n is uninitialized. There's no knowing how large these arrays will be. You loops are almost certainly accessing the array out of bounds.
You want to read n, then create the arrays. Of course you also want to error check the result of scanf.
int n; // n is use to decide the size of array
printf("enter the size of array:");
scanf("%d", &n);
int x[n];
int y[n];
I'm writing a program which scanf integers and printf in double.
Here is my code:
int main(void) {
int arraySize;
scanf("%d",&arraySize);
double vector[arraySize];
for(int i=0;i<arraySize;i++) scanf("%lf", &vector[i]);
for(int a=0;a<arraySize;a++) printf("VECTORS:[%lf]",vector[a]);
}
Since I need to for loop every element in the array then printf all of them one by one.
this is the output I had:
VECTORS:[1.000000] VECTORS:[2.000000] VECTORS:[3.000000]
How can I change the format of the printf function and get ouput like this:
VECTOR: [ 1.000, 2.000, 3.000 ]
Your one major mistake is your array size. I know your compiler won't issue any warning but this is not any feature which language provide so size must be a
constant numerical value or const expression.
So in short you can't create array After asking size from user. This is completely wrong.
int arraySize;
scanf("%d",&arraySize);
double vector[arraySize];
You must make size const. If you want less values than the declared size you can decrease the no of times for loop will run but you can't decide array size as inputted by user.
const int size = 10; // this is how your size should be. Even your compiler allowed VLA you should not try this. size of arrays must be constant.
int main()
{
unsigned int i,s;
int arr[size];
printf ("Enter the size of array.");
scanf("%d",&s);
for(i = 0 ; i<s;i++){
scanf("%d",&arr[i]);
}
for(i = 0 ; i<s;i++){
arr[i] = arr[i]*arr[i];
}
for(i = 0 ; i<s;i++){
printf("%d",arr[i]);
}
}
Print VECTOR once then loop over all the vectors and output them in the desired format.
const int size = 10;
int main(void) {
double vector[size];
for(int i=0;i<size;i++)
scanf("%lf", &vector[i]);
printf("VECTOR: [ ");
for(int a=0;a<size;a++){
printf("%lf", vector[a]);
if(i < size - 1)
printf(", ");
}
printf(" ]");
}
You need to allocate memory dynamically to use it.
Use the printf in the code below to define precision.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int arraySize = 0;
scanf("%d",&arraySize);
double *vector = (double *) calloc(arraySize, sizeof(double));
for(int i=0; i<arraySize; i++) {
scanf("%lf", &vector[i]);
}
printf("VECTORS:[");
int a;
for(a=0;a<arraySize;a++) {
printf(" %.3lf",vector[a]);
if (a<(arraySize-1)) {
printf(",");
} else {
printf(" ");
}
}
printf("]");
}
Change your for loop to take 3 elements at once.
for(a=0;a<arraySize;a+=3) {
printf("VECTORS:[%lf", vector[a]);
if (a+1 < arraySize) printf(", %lf", vector[a+1]);
if (a+2 < arraySize) printf(", %lf", vector[a+2]);
printf("]\n");
}
I am new to Programming and to Stack overflow, so forgive me if I make any mistakes. I have this program where one array of ints is split into two other arrays depending on if they are larger or smaller than a user inputted int. Right now all the smaller and larger arrays do is copy the first integer regardless of the number put in. Any suggestions/critiques?
/*
This program will separate an input array into two arrays. One array will be filled by
elements greater than a specified number and the other array will be filled by elements
less than the specified number.
*/
#include <stdio.h>
void separate(int *a, int n, int value, int *larger, int *size, int *smaller);
int main()
{
//Find size of array
int length;
int *length_pointer = &length;
printf("Enter the length of the array: ");
scanf("%d", length_pointer);
//Enter array elements
int array[length], *p;
printf("Enter %d numbers: ", length);
for(p = array; p < array + length; p++)
scanf("%d", p);
//Find separating value
int value;
printf("Enter the number to split the array: ");
scanf("%d", &value);
//Declare arrays and call function
int n = 0, larger[length], smaller[length];
separate(array, n, value, larger, length_pointer, smaller);
//Display the arrays
printf("%d\n", *smaller);
printf("%d", *larger);
return 0;
}
/*************************************************************************************
separate finds numbers larger than value in array a and stores them in array larger.
Numbers smaller than or equal to value will be stored in the smaller array.
size points to a variable in which the function will store the number of larger
numbers in the array.
*************************************************************************************/
void separate(int *a, int n, int value, int *larger, int *size, int *smaller)
{
// Delete later *smaller = *larger = *a;
for(a = &n; a < n + size; a++)
if(a[n] > value)
{
larger = &a[n];
}
else if(a[n] <= value)
smaller = &a[n];
return;
}
I modified a bit your code to reach your goal. In order to get array size from user input under C99, you need to dynamically assign it e.g. by calloc(elements_number, element_size_in_bytes) when your program runs. Don't forget to free assigned memory to avoid memory leaks. Like below:
int* array = calloc(user_input, sizeof(int));
...
//some code
...
free(array);
Your separate function looks a bit complex. This part is wrong:
for(a = &n; a < n + size; a++)
What you are doing here is making a point to integer n. a does not point anymore to a source array. So making a call like a[n] when a is &n is like (&n)[n]. n is not changing value also, because you increment pointer to n, not the value it points to.
Next if you want to display array elements do it by using loop, like I did below.
I could not find the purpose of n parameter in your separate function. I used it as amount of real elements in larger array, so I don't have to print all elements.
I hope this answer meats your expectations.
#include <stdio.h>
#include <stdlib.h>
void separate(int *a, int *larger_count, int value, int *larger, int size, int *smaller);
int main()
{
//Find size of array
int length;
int *length_pointer = &length;
printf("Enter the length of the array: ");
scanf("%d", length_pointer);
//Enter array elements
int*array = calloc(*length_pointer, sizeof(int));
int*p;
printf("Enter %d numbers: ", length);
for(p = array; p < array + length; p++)
scanf("%d", p);
//Find separating value
int value;
printf("Enter the number to split the array: ");
scanf("%d", &value);
//Declare arrays and call function
int *larger = calloc(*length_pointer, sizeof(int));
int *smaller = calloc(*length_pointer, sizeof(int));
int larger_count = 0;
separate(array, &larger_count, value, larger, length, smaller);
for (int i = 0 ; i < larger_count ; ++i)
{
printf("%d ", larger[i]);
}
printf("\n");
for (int i = 0 ; i < length - larger_count; ++i)
{
printf("%d ", smaller[i]);
}
printf("\n");
free(array);
free(larger);
free(smaller);
return 0;
}
/*************************************************************************************
separate finds numbers larger than value in array a and stores them in array larger.
Numbers smaller than or equal to value will be stored in the smaller array.
size points to a variable in which the function will store the number of larger
numbers in the array.
*************************************************************************************/
void separate(int *a, int *larger_count, int value, int *larger, int size, int *smaller)
{
for(int x = 0, y = 0, z = 0; x < size; x++)
{
if (a[x] > value)
{
larger[y] = a[x];
y++;
*larger_count = y;
} else
{
smaller[z] = a[x];
z++;
}
}
}
I am trying to scanf values to an array from another function using pointer to pointer. Here's the code:
int initialize(int **arr, int count);
int main()
{
int count;
int *numbers;
scanf("Enter the amount of numbers to enter: %d", &count);
initialize(&numbers, count);
free(numbers);
return 0;
}
int initialize(int **arr, int count)
{
int i = 0;
*arr = calloc(count, sizeof(int));
while(i < count)
{
printf("Nr. %d: ", i + 1);
scanf("%d", &arr[i]);
i++;
}
return 0;
}
It allocates the memory correctly, however, there seems to be a problem inside scanf function in initialize so it crashes after reading in first 2 numbers. Could you help solve it?
arr is a pointer to pointer to int, so 1st make it a pointer to int (before using it like an array) by doing *arr.
So this
scanf("%d", &arr[i]);
should be
scanf("%d", &(*arr)[i]);
or its shorter equivalent
scanf("%d", *arr + i);
Unrelated, but in C it should be at least
int main(void)
Unrelated^2: Sizes and indexes in C best are defined using size_t (coming with stdlib.h).
So the relevant part of your code would look like this:
int main(void)
{
size_t count;
int *numbers;
scanf("Enter the amount of numbers to enter: %zu", &count);
...
int initialize(int **arr, size_t count)
{
size_t i = 0;
*arr = calloc(count, sizeof(int));
while (i < count)
...
Last not least the code misses error checking for the relevant functions:
scanf()
calloc()
Error checking (along with logging the errors) is debugging for free!
So I'm having some issues with a program I'm writing to calculate statistics of an arbitrary amount of numbers. As you probably know, C does not have a native way of growing an array based on user input, so I made one. I'm not too familiar with pointers as I have not learned them yet. However, the main issue I'm having is that my program will not allow me to input anymore than 16 numbers. Any ideas on why?
#include <stdio.h>
#include <math.h>
float getMin(float arr[], int size)
{
int i;
float minimum = arr[0];
for (i=1; i < size; i++) {
if (arr[i] < minimum) {
minimum = arr[i];
}
}
return(minimum);
}
float getMax(float arr[], int size)
{
int i;
float maximum;
for(i=0; i<size; i++) {
if (arr[i] > maximum) {
maximum = arr[i];
}
}
return(maximum);
}
float getAverage(float arr[],int size)
{
int i;
float avg, sum;
for(i=0; i<size; i++) {
sum += arr[i];
}
avg = sum/size;
return avg;
}
float getVar(float arr[], int size, float average)
{
int i;
float var, diff[size], sq_diff[size], sum;
for(i=0; i<size; i++) {
diff[i] = arr[i] - average;
}
for(i=0; i<size; i++)
{
sq_diff[i] = pow(diff[i], 2);
}
var=getAverage(sq_diff, size);
return(var);
}
float getStdDev(float var)
{
float std_dev = sqrt(var);
return(std_dev);
}
int main(void)
{
int n=0, i=0;
float array[n], x;
printf("This program computes 1-D statistics.");
printf("\nEnter a negative number to stop input.\n");
do {
printf("Number %d: ", i+1);
scanf("%f", &x);
n++;
array[i] = x;
i++;
}while(x >= 0);
float avg = getAverage(array, n-1);
float var = getVar(array, n-1, avg);
printf("\nMinimum: %f", getMin(array, n-1));
printf("\nMaximum: %f", getMax(array, n));
printf("\nAverage: %f", getAverage(array, n-1));
printf("\nVariance: %f", getVar(array, n-1, avg));
printf("\nStandard Deviation: %f", getStdDev(var));
return(0);
}
I am afraid you have some general miss-understanding of how C and programming languages work in general. Programming is not exactly the same as math. If you declare a variable n and an array myarr[n], your array won't grow as n grows. The array will take the value n had at the point you declared it and will use that. Also declaring arrays like that is probably not a good idea, I don't think many C compilers will compile what one would expect. In your case you are declaring an array of size 0, the fact that it seems to work up to 16 numbers is completely system dependent. You can not expect this kind of behavior to be consistent over different systems/compilers.
Instead what you should do if you really need this is use dynamic memory. I have written a simple example really fast you could use. This is by no means a complete but for your needs it should be good enough. Use the initArr(&arr) whenever you create a new growing array. If for example you have an array of type MyArr with name arr you can get the data of the array like this arr.data[i] while you can get the length of the array (the meaningful data) like this arr.len. Finally you can get the current max size of your array like this arr.size. Please not that you should only add new elements using addElement(&arr, x) as this function will take care of the array growth. When you are done using your array you can use destrArr(&arr) to free the memory. This is good practice even though when your program exits the memory is freed anyway.
Finally please review your functions. I haven't been through your logic but remember that you should never exceed boundaries. For example you should not try to access array[-1] or array[size_of_array] where size_of_array is the total size of your array. Remember that an array declared as float arr[100] can only safely be used in the region arr[0] to arr[99]. Also doing sum += x is equivalent to doing sum = sum + x. Consider what the initial value of sum is if you do not initialize it. In fact it depends but could contain garbage values.
Try looking at your compiler warnings and fix them. It is worth understanding them and are rarely worth neglecting. Try the -Wall flag if you are using gcc, it might give you some more warnings worth looking at.
I hope this was helpful and not too confusing. In any case have a look at the following code and add your functions and libraries back. This should work out of the box.
Good Luck! :)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INIT_SIZE 2
typedef struct MyArr {
float *data;
int size;
int len;
} MyArr;
int initArr(MyArr *arr) {
arr->data = (float *)malloc(INIT_SIZE*sizeof(float));
if (arr->data == NULL) {
printf("OUT OF MEMORY\n");
return -1;
}
arr->size = INIT_SIZE;
arr->len = 0;
return 1;
}
int addElement(MyArr *arr, float x) {
if (arr->len == arr->size) {
int i;
float *tmp = (float *)malloc(2*arr->size);
if (tmp == NULL) {
printf("OUT OF MEMORY\n");
return -1;
}
for (i = 0; i < arr->size; ++i) {
tmp[i] = arr->data[i];
}
free(arr->data);
arr->data = tmp;
arr->size = 2*arr->size;
}
arr->data[arr->len] = x;
arr->len++;
return 1;
}
void destrArr(MyArr *arr) {
free(arr->data);
arr->size = 0;
arr->len = 0;
}
int main(void)
{
int n=0, i=0;
float x;
MyArr array;
initArr(&array);
printf("This program computes 1-D statistics.");
printf("\nEnter a negative number to stop input.\n");
do {
printf("Number %d: ", i+1);
scanf("%f", &x);
n++;
addElement(&array, x);
i++;
}while(x >= 0);
float avg = getAverage(array.data, n-1);
float var = getVar(array.data, n-1, avg);
printf("\nMinimum: %f", getMin(array.data, n-1));
printf("\nMaximum: %f", getMax(array.data, n));
printf("\nAverage: %f", getAverage(array.data, n-1));
printf("\nVariance: %f", getVar(array.data, n-1, avg));
printf("\nStandard Deviation: %f", getStdDev(var));
destrArr(&array);
return(0);
}