I need help. First time writing C - arrays

Can someone help me fixing the syntax errors in this code?
#include <stdio.h>
int result(int v, int size);
int main(void){
int arr[5], n;
for (n = -1; n < 4; n++){
arr[n] = n + 1;
printf("the product of entered values is %d", result(n, 5));
}
return 0;
}
int product(int a[]) {
int product, i;
for (i = 0; i <= sizeof(int); i++){
product *= a[i];
}
return product;
}

for (n = -1; n < 4; n++){
arr[n] = n + 1;
You start n at -1, then immediately use arr[n].
Negative indices are not allowed in C. Valid values are 0 to the size of the array-1.In otherwords, if you have an arr[5], then the valid indices are [0], [1], [2], [3], and [4].
int product(int a[]) {
int product, i;
You create a function named product and also a variable named product.
That makes it virtually impossible to refer to the proper object. Work on your name management, so that every item is unambiguous.

You are trying to call the result function, for which you have provided the forward declaration but not an actual implementation. You need to write an implementation for the result function. That is why the compiler complains about an undefined reference.

For starters the function result is declared
int result(int v, int size);
but not defined.
On the other hand, taking into account the message in this call of printf
printf("the product of entered values is %d", result(n, 5));
you mean a function that calculates a product of elements of an array like your function defined after main but that is not used
int product(int a[]) {
int product, i;
for (i = 0; i <= sizeof(int); i++){
product *= a[i];
}
return product;
}
So let's remove the declaration of the function result and declare before main a function with name product because the name result is not enough informative.
The function deals with an array. We need to pass to the function the number of elements in the array. As the array itself will not be changed within the function then it should be declared with the qualifier const
Also a product of integer numbers of the type int can be too big to be stored in an object of the type int.
So it is better to declare the return type of the function at least like long long int (or even like double or long double).
Thus the function declaration can look like
long long int product( const int a[], size_t n );
The function can be defined the following way
long long int product( const int a[], size_t n )
{
long long int result = n == 0 ? 0 : 1;
for ( size_t i = 0; i < n; i++ )
{
result *= a[i];
}
return result;
}
As for your function product then you forgot to initialize the variable product
int product, i;
The condition in the for loop
for (i = 0; i <= sizeof(int); i++){
does not make a sense because the expression sizeof( int ) does not yield the number of elements in an array.
Try to not use magic numbers like 5 in this declaration
int arr[5], n;
in your programs. Use named constants.
Indices of arrays always start from 0. So this loop
for (n = -1; n < 4; n++){
where the variable n is used as an index does not make sense.
Also this call of printf
printf("the product of entered values is %d", result(n, 5));
must be placed outside the for loop and in the the call of the function result that is used as an argument of the function printf
result(n, 5)
you even are not using the array.
Thus the program can look the following way
#include <stdio.h>
long long int product( const int a[], size_t n );
int main(void)
{
enum { N = 5 };
int a[N];
for ( size_t i = 0; i < N; i++ )
{
a[i] = i + 1;
}
printf( "The product of entered values is %lld", product( a, N ) );
return 0;
}
long long int product( const int a[], size_t n )
{
long long int result = n == 0 ? 0 : 1;
for ( size_t i = 0; i < n; i++ )
{
result *= a[i];
}
return result;
}
The program output is
The product of entered values is 120

Related

How to get all the elements of an array that are divisible with 3 and then sum them thogether?

I dont know how to get the code to print out the elements that are divisable with 3 and the print out the sum of those elements , can someone help me do it , thanks for your time!
Code:
#include <stdio.h>
int sum(int arr[]){
int n = sizeof(arr) / sizeof(arr[0]);
int sum = 0;
for (int y=0;y<n;y++){
sum += arr[y];
printf("%d",sum);
}
}
int main() {
int F[5] = {1,3,5,9,8};
int s = 0;
for (int i=0;i<5;i++){
if (F[i]%3 == 0) {
int diviz[] = {F[i]};
printf("%d\n",diviz[0]);
sum(diviz);
}
}
return 0;
}
Expected Output:
3
9
12
Actual Output:
3
349
910
Idk how to solve this issue
This function declaration
int sum(int arr[]){
is adjusted by the compiler to the declaration
int sum(int *arr){
That is within the function the variable arr has the pointer type int *.
Thus the declaration with sizeof expression
int n = sizeof(arr) / sizeof(arr[0]);
is equivalent to
int n = sizeof( int * ) / sizeof( int );
and yields either 2 or 1 depending on the size of the pointer.
On the other hand, this call of the function
int diviz[] = {F[i]};
printf("%d\n",diviz[0]);
sum(diviz);
in any case does not make a great sense because instead of passing the original array you are passing an array that contains only one element. And the for loop in main is redundant.
You need explicitly to pass the number of elements in the array.
So the function can look like
long long int sum( const int arr[], size_t n, int divisor )
{
long long int sum = 0;
for ( size_t i = 0; i < n; i++ )
{
if ( arr[i] % divisor == 0 ) sum += arr[i];
}
return sum;
}
And the function can be called like
int arr[] = {1,3,5,9,8};
const size_t N = sizeof( arr ) / sizeof( *arr );
int divisor = 3;
printf( "The sum of elements divisible by %d = %lld\n", divisor, sum( arr, N, divisor ) );
The function will be more safer if to add a check whether divisor is passed equal to 0 as for example
long long int sum( const int arr[], size_t n, int divisor )
{
long long int sum = 0;
if ( divisor != 0 )
{
for ( size_t i = 0; i < n; i++ )
{
if ( arr[i] % divisor == 0 ) sum += arr[i];
}
}
return sum;
}
int main() {
int F[5] = {1,3,5,9,8};
int s = 0;
for (int i=0;i<5;i++){
if (F[i]%3 == 0) {
s = s + F[i];
printf("%d",F[i]);
}
}
printf("%d",s); //print sum total
return 0;
}

multi pointers in function in c

i'm not good at english.
i declare array and two pointers.
the maxPtr pointer should have array arr's maximum number adress.
and minPtr pointer should have array arr's minimum number adress.
so i declare the function and this has two double-pointer to give maxPtr and minPtr proper adress.
but whenever i run this code, the program is not fully run.
it doesn't output the result( printf("%d",*maxPtr) ,printf("%d", *minPtr, printf("Hi");
this program is run at vscode in mac.
what make it error?
#include <stdio.h>
void MaxAndMin(int* str,int** max, int** min)
{
int i;
int maxnum=0,minnum=0;
for(i=0; i<5; i++)
{
if(maxnum< str[i])
{
maxnum =str[i];
*max = &str[i];
}
if(minnum > str[i])
{
minnum = str[i];
*min = &str[i];
}
}
}
int main(void)
{
int i,len;
int* maxPtr;
int* minPtr;
int arr[5]={};
for(i=0; i<5; i++)
{
printf("%d번째 정수입력 입니다.",i+1);
scanf("%d", &arr[i]);
}
MaxAndMin(arr,&maxPtr,&minPtr);
printf("%d",*maxPtr);
printf("%d",*minPtr);
printf("Hi");
return 0;
}
the result is
> Executing task: ./test <
1번째 정수입력 입니다.1
2번째 정수입력 입니다.2
3번째 정수입력 입니다.3
4번째 정수입력 입니다.4
5번째 정수입력 입니다.5
Terminal will be reused by tasks, press any key to close it.
For starters this initialization of an array
int arr[5]={};
is incorrect in C. You have to write
int arr[5]={ 0 };
Secondly using the magic number 5 within the function makes the function useless in general. You need to pass to the function the size of the array.
The initial value 0
int maxnum=0,minnum=0;
of these variables makes the function even more less useful. In general the array can contain either all elements positive or all elements negative.
And you need to flush the output buffer using for example the new line character '\n' in calls of printf.
The function can be declared and defined the following way as it is shown in the demonstration program below.
#include <stdio.h>
void MaxAndMin( const int a[], size_t n, int **max, int **min )
{
*max = ( int * )a;
*min = ( int * )a;
for ( size_t i = 1; i < n; i++ )
{
if ( **max < a[i] )
{
*max = ( int *)( a + i );
}
else if ( a[i] < **min )
{
*min = ( int * )( a + i );
}
}
}
int main( void )
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
int *maxPtr = NULL;
int *minPtr = NULL;
MaxAndMin( a, N, &maxPtr, &minPtr );
printf( "The maximum value is %d at position %tu\n",
*maxPtr, maxPtr - a );
printf( "The minimum value is %d at position %tu\n",
*minPtr, minPtr - a );
}
The program output is
The maximum value is 9 at position 9
The minimum value is 0 at position 0
Pay attention to that the first parameter of the function should have the qualifier const because passed arrays to the function are not changed within the function.
The main issue is that the minnum is set at zero, which would only work if array had a negative value.
Setting minimum = star[0] also would not work!!! Because in the case of str[0] having negative value, *min never gets changed.
Also, I recommend to always initialize all variables in the declaration, especially pointers (because they may theoretically cause accidental access to memory).
Full solution:
#include <stdio.h>
int MaxAndMin(int* str, int** max, int** min)
{
int i;
int maxnum = 0;
int minnum = str[0] + 1;
for(i=0; i<5; i++)
{
if(maxnum < str[i])
{
maxnum = str[i];
*max = &str[i];
}
if(minnum > str[i])
{
minnum = str[i];
*min = &str[i];
}
}
return 0;
}
int main(void)
{
int i = 0;
int len = 0;
int* maxPtr = NULL;
int* minPtr = NULL;
int arr[5]={};
for(i=0; i<5; i++)
{
printf("Enter number %d: ",i+1);
scanf("%d", &arr[i]);
}
MaxAndMin(arr, &maxPtr, &minPtr);
printf("%d",*maxPtr);
printf("%d",*minPtr);
printf("Hi");
return 0;
}

empty pointers as an argument in C - problem with asterisks

The task is to fill an array with numbers by user input and then use our stats() function to calculate average etc. of each row of this array. The header of stats() function looks as follows:
int stats(int (*ptr)[5], int width, int height, int row_id, int* max, int* min, float *avg)
where ptr is a pointer to the matrix,width and height are its size, row_id is the index of analysed row and max, min and avg are pointers to variables storing each statistics.
When calling a function with such line:
stats(*ptr, 5,5,2, *max = NULL, *min = NULL, *avg=NULL);
the following error appears:
error: invalid type argument of unary '*' (have 'int')
I tried different approaches but there is always a mistake, how can I fix that? Thank you for any clues.
edit:
Here's the whole code:
#include <stdio.h>
int stats(int (*ptr)[5], int width, int height, int row_id, int* max, int* min, float *avg)
{
int j, vmax,vmin;
int max = &vmax;
int min = &vmin;
int i = row_id;
int m = *ptr;
for(j = 0; j<5; j++){
if(m[i][j]>max)
{
max = m[i][j] ;
j++;
else
j++;
}
}
printf("%d", max);
return 0;
}
int main(void){
int n, i, j, vmin, vmax; // vmax - value of the maximum
int min = &vmin; // min - pointer to the minimum
int max = &vmax;
float vavg;
int avg = &vavg;
int m[5][5];
for(i = 0; i<5; i++)
{
for(j = 0; j<5; j++)
{
printf("ENTER A NUMBER: ");
scanf("%d", &n);
m[i][j] = n;
}
}
int ptr = &m;
stats(*ptr, 5,5,2, *max = NULL, *min = NULL, *avg=NULL);
return 0;
}
Your code full of bugs.
For example min and max are not declared as pointers
int min = &vmin; // min - pointer to the minimum
int max = &vmax;
Also it is unclear why the variable avg has the type int and is initialized by a pointer expression of the type float *.
float vavg;
int avg = &vavg;
Or the variable ptr of the type int is initialized by the address of the two-dimensional array.
int ptr = &m;
As for the function then if the function operates only on one row then there is no any sense to pass to the function the whole two-dimensional array.
Also the return type and the returned value of the function do not make a sense.
And the function shall not output any message. It is the caller of the function that will decide output a message or not.
And also the function contains bugs where you are redeclaring its parameters like for example
int max = &vmax;
that again does not make a sense.
Using your approach the function can be declared and defined the following way
#include <assert.h>
//...
void stats( const int *a, size_t n, int *max, int *min, float *avg )
{
assert( n != 0 );
*max = a[0];
*min = a[0];
float sum = a[0];
for( size_t i = 1; i < n; i++ )
{
sum += a[i];
if ( *max < a[i] )
{
*max = a[i];
}
else if ( a[i] < *min )
{
*min = a[i];
}
}
*avg = sum / n;
}
And called like
int min = 0;
int max = 0;
float avg = 0.0f;;
//...
stats( m[2], 5, &max, &min, &avg );
printf( "max = %d\n", max );
printf( "min = %d\n", min );
printf( "average = %f\n", avg );
When you are using pointers as function parameters be carefull. If you have something like this:
int func(int *max){
}
max ,here, is a pointer which needs to hold an address. So inside this function when you need use it, you need to dereference it by using *. For example:
int func(int *max){
*max = $someAddress
}

multiplying the elements of an array - converting a for loop into a while loop

so I figured out how to write this using a for loop
int mult_for(int* array, int len) {
int mult = 1;
for (int i = 0; i < len; i++) {
mult *= array[i];
}
return mult;
}
but I'm unsure of how to go about doing the same thing using while.
int mult_while(int* array, int len) {
int mult = 1;
while (int i < len){
mult *= array[i]
}
return 0;
}
I currently have this but am unsure of how to continue from there. The syntax of c is still new, so that doesn't help either.
For loop uses for(initialization; condition; increment/decrement) { body } syntax, which is a common rule for most languages.
The aforementioned three phases (initialization, condition and increment/decrement) are present in every variation of loop, and for a while loop they follow this order:
initialization
while(condition)
{
body
increment/decrement
}
For your case:
int i = 1; //initialization
while (i < len) //while(condition)
{
mult *= array[i]; //body
i++; //increment
}
Note that:
Initialization here refers to initializing the variable(s) to be used inside the loop. There can be multiple variables.
Increments/Decrements can come before/after the loop body.
You can also have a while loop without defining extra loop variables. Such as in your case, if your using the pre-defined len variable in your code, you can use it as a condition to loop till the value becomes zero by using while(len--) { body }, thereby reducing the need for an extra variable and its subsequent increment/decrement statement.
It is my first see that int type-definer as a condition over a while loop. Anyway, you need to increase your counter, i.e. i, one by one to iterate the array over. It stops when i == len as alike happened in your for-loop example.
int mult_while(int* array, int len)
{
int mult = 1;
int i = 0;
while (i < len) {
mult *= array[i];
++i;
}
return mult; // the result must be returned in lieu of zero
}
You can easily do it by continuously decrementing len until it hits 0:
int mult_while(int const* array, int len) {
int mult = 1;
while(len--) {
mult *= *array++;
}
return mult;
}
For starters the function should be declared like
long long int mult_while( const int *array, size_t len );
that is the return type should be long long int to avoid overflowing. And the pointer should be declared with the qualifier const because the array is not being changed within the function. The size of the array should have the type size_t,
You need not to declare one more local variable apart from the parameters as it was done in the for loop in your first function implementation.
The function can be implemented the following way using the while loop.
long long int mult_while( const int *array, size_t len )
{
long long int mult = len == 0 ? 0 : 1;
while ( len-- ) mult *= array[len];
return mult;
}
Pay attention to that in general the user can pass the length of the array equal to 0. In this case it will be logically consistent to return 0.
Here is a demonstrative program.
#include <stdio.h>
#include <limits.h>
long long int mult_while( const int *array, size_t len )
{
long long int mult = len == 0 ? 0 : 1;
while ( len-- ) mult *= array[len];
return mult;
}
int main(void)
{
int a[] = { INT_MAX, INT_MAX };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
printf( "The product of the array elements is equal to %lld\n", mult_while( a, N ) );
return 0;
}
The program output is
2147483647 2147483647
The product of the array elements is equal to 4611686014132420609
As you can see for such big numbers stored in the array the result is correct.
It is the only function implementation among presented here in answers that is more or less correct.

Enumerate and return all the combinations of choosing k out of n items in a 2-dimensional array from a recursive function in C

I am using a recursive function (from one of the posts here) to enumerate all combinations of selecting k items out of n. I have modified this function to save and return the enumerated combinations in a 2-dimensional array (which is passed to the function as arrPtr). I call this recursive function in a for loop (from main) for different values of k (k from 1 to n-1) to generate all the combinations for any value of n and k. Now, with 'count', being defined as static integer, the function generates all the combinations for k=1 and then goes to k=2, but then stops at one point. The reason is that I'm using the variable 'count' as an index for rows in arrPtr. Since it is a static variable, it does not reset to 0 when the function is called for the other rounds (k=2,3,4 etc.). So it results in access violation for arrPtr after a certain point. When I remove 'static' for 'count', it generates all the combinations for different values of k, but only the last combination in each round is saved in arrPtr (again due to removing 'static'). How can I save each generated combination in a row in arrPtr so I can get (and return) all of the combinations saved in one place pointed to by arrPtr at the end?
I tried to pass the index for rows in arrPtr to the function using pass by reference (passing the address of the variable) but that gets into trouble when the recursive function calls itself.
I searched a lot and found similar topics here (e.g., returning arrays from recursive functions), but they are mostly for other programming languages (I only use C; not even C++). I have spent many many hours on solving this and really need help now. Thank you in advance.
int** nCk(int n,int loopno,int ini,int *a,int **arrPtr, int k)
{
static int count=0;
int total; // equal to the total number of combinations of nCk
int i,j;
total = factorial(n)/(factorial(n-k)*factorial(k));
loopno--;
if(loopno<0)
{
a[k-1]=ini;
for(j=0;j<k;j++)
{
printf("%d,",a[j]);
arrPtr[count][j]=a[j];
}
printf("count =%d\n",count);
count++;
return 0;
}
for(i=ini;i<=n-loopno-1;i++)
{
a[k-1-loopno]=i+1;
nCk(n,loopno,i+1,a,arrPtr,k);
}
if(ini==0)
return arrPtr; // arrPtr is in fact an array of pointers, where each pointer points to an array of size k (one of the combinations of selecting k out of n elements
else
return 0;
}
what i understand is
you want to calculate the combination for any value of n and k in nCk,
define a factorial() function outside and
define a combi() function ... which calculates Combination value of n and k variables
both function before defining the main() function... that way you can avoid declaration and then defining (i mean avoid extra lines of code).
here is the code for combi() function
function combi(int n , int k){
int nFact, kFact, n_kFact, p;
int comb;
nFact=factorial(n);
kFact=factorial(k);
p=n-k;
n_kFact=factorial(p);
comb= nFact / ((n_kFact) * kFact);
return comb;
}
you can call this function in your main function .... use for loop to store the combination value for relative n and k .... thus you will get what you need .... also pass pointer or
&array[0][0]
i.e. starting address for the array... so that you can access that array anywhere in the program.
hope this may help you. thanks
GCC 4.7.3: gcc -Wall -Wextra -std=c99 enum-nck.c
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// Textbook recursive definition of, n-choose-k.
int nCk(int n, int k) {
assert(0 < k && k <= n);
if (k == n) { return 1; }
if (k == 1) { return n; }
return nCk(n - 1, k) + nCk(n - 1, k - 1);
}
// But you asked for a procedure to enumerate all the combinations.
void aux_enum_nCk(int n, int k, int* all, int* j, int a[], int i) {
a[i] = n;
if (i == k - 1) {
memcpy(&all[*j], &a[0], k * sizeof(int));
*j += k;
return;
}
for (int c = n - 1; c > 0; --c) {
aux_enum_nCk(c, k, all, j, a, i + 1);
}
}
void enum_nCk(int n, int k, int* arr) {
assert(0 < k && k <= n);
int j = 0;
int a[k];
for (int i = 0; i < k; ++i) { a[i] = 0; }
for (int c = n; c >= n - k - 1; --c) {
aux_enum_nCk(c, k, arr, &j, a, 0);
}
}
int main(int argc, char* argv[]) {
int n = 7;
int k = 3;
int x = nCk(n, k);
printf("%d choose %d = %d\n", n, k, x);
int arr[x][k];
enum_nCk(n, k, &arr[0][0]);
for (int i = 0; i < x; ++i) {
for (int j = 0; j < k; ++j) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}

Resources