why does GCC "expect an expression"? - c

#define rows 2
#define cols 2
#define NUM_CORNERS 4
int main(void) {
int i;
int the_corners[NUM_CORNERS];
int array[rows][cols] = {{1, 2}, {3, 4}};
corners(array, the_corners);
for (i = 0; i < 4; i++) printf("%d\n", the_corners[i]);
}
int corners (int array[rows][cols], int the_corners[]) {
the_corners = {
array[0][cols-1],
array[0][0],
array[rows-1][0],
array[rows-1][cols-1]
};
}
I get these weird errors and i have no idea why:
prog.c: In function ‘main’:
prog.c:10: warning: implicit declaration of function ‘corners’
prog.c: In function ‘corners’:
prog.c:15: error: expected expression before

The the_corners = { ... } syntax is an array initialization, not an assignment. I don't have a copy of the standard handy so I can't quote chapter and verse but you want to say this:
void corners (int array[rows][cols], int the_corners[]) {
the_corners[0] = array[0][cols-1];
the_corners[1] = array[0][0];
the_corners[2] = array[rows-1][0];
the_corners[3] = array[rows-1][cols-1];
}
I also took the liberty of changing int corners to void corners as you weren't returning anything. And your main also needs a return value and you forgot to #include <stdio.h>.

You're trying to use an initialiser expression as an assignment. This isn't valid, even in C99, because the type of the_corners is int*, not int[4]. In this case you would be best off assigning each element individually.

The main doesn' know about your function. Either move the function decleration above the main or prototype it before the main:
int corners (int array[rows][cols], int the_corners[NUM_CORNERS]);

Try this one:
#include <stdio.h>
#define NROWS 2
#define NCOLUMNS 2
#define NCORNERS 4
int corners(int (*arr)[NCOLUMNS], int* the_corners);
int main() {
int i;
int the_corners[NCORNERS];
int arr[NCOLUMNS][NROWS] = {{1, 2}, {3, 4}};
corners(arr, the_corners);
for (i = 0; i < NCORNERS; i++)
printf("%d\n", the_corners[i]);
return 0;
}
int corners(int (*arr)[NCOLUMNS], int* the_corners) {
the_corners[0] = arr[0][NCOLUMNS-1];
the_corners[1] = arr[0][0];
the_corners[2] = arr[NROWS-1][0];
the_corners[3] = arr[NROWS-1][NCOLUMNS-1];
return 0;
}
You can read here about passing a 2D array to a function.

Related

struct and typedef initialization

I am not sure why I am not getting a display on the console for the value of maxProd. I think I am declaring the arr_integer array variable wrong in main?
I ran a couple tests and the program looks like it does not even get to call solution().
Any help would be greatly appreciated. I am trying to get this to work and get rid of the following warnings;
Adjacent_Element_Product.c:31:40: note: (near initialization for 'array')
Adjacent_Element_Product.c:31:43: warning: excess elements in struct initializer
#include <stdio.h>
typedef struct arr_integer {
int size;
int *arr;
} arr_integer;
arr_integer alloc_arr_integer(int len) {
arr_integer a = {len, len > 0 ? malloc(sizeof(int) * len) : NULL};
return a;
}
int solution(arr_integer inputArray) {
int maxProd = inputArray.arr[0] * inputArray.arr[1];
for (int i = 1; i < inputArray.size - 1; i++)
{
int product = inputArray.arr[i] * inputArray.arr[i + 1]; //multiple next door neighbours.
if (product > maxProd)
maxProd = product;
}
return printf("maxProd: %d\n", maxProd);
}
int main()
{
arr_integer array = {3, 6, -2, -5, 7, 3};
solution(array);
return 0;
}
The problem is that you don't allocate memory for the array and that it then tries to use the list of integers as an int*.
A possible remedy:
#define Size(x) (sizeof (x) / sizeof *(x))
int main() {
int ints[] = {3, 6, -2, -5, 7, 3};
arr_integer array = {.size = Size(ints), .arr = ints};
solution(array);
}
Here are the relevant changes:
added <stdlib.h> for malloc
eliminated alloc_arr_integer() which was not used
maxProd is initialized to INT_MIN and tweaked initial loop condition to reduce duplication
to make the solution a little smaller passing the value inline to solution (#TedLyngmo probably gave you a better solution)
Not fixed:
arr_integer doesn't seem to add any value so maybe just pass size and array to solution(). You could create a macro to initialize it using the approach #TedLyngmo shared with you. It has to be a macro as int [] degrades to int * in a function call, and the latter (silently?) gives you the wrong result which makes it error prune.
Does negative size make sense? If not then use an unsigned type.
What is the solution if size < 2?
solution() returns the value from printf() which is strange. You might want to return maxProd and have main() print out the value. This makes your function testable
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct arr_integer {
int size;
int *arr;
} arr_integer;
int solution(arr_integer inputArray) {
int maxProd = INT_MIN; // what is answer if size < 2? error?
for (int i = 0; i < inputArray.size - 1; i++) {
int product = inputArray.arr[i] * inputArray.arr[i + 1]; //multiple next door neighbours.
if (product > maxProd)
maxProd = product;
}
return printf("maxProd: %d\n", maxProd);
}
int main() {
solution((arr_integer) {
6,
(int []) { 3, 6, -2, -5, 7, 3 }
});
return 0;
}
and the output is:
maxProd: 21

Foreach function in C

I want to create a function that takes a array and a function and calls that function on each element in the array
I've looked around for a solution but they all seem to use macros whereas I would prefer a function if at all possible.
I'm looking for something that would work something like the following
void print_string()
{
printf("%d\n", num);
}
int array[] = { 1, 2, 3, 4, NULL }; // So the foreach function knows when it has reached the end
for_each_function(array, print_number);
Outputting:
1
2
3
4
Edit: It needs to be generic so it will probably require a macro
You should probably use function pointers. One complete implementation using function pointers is like this.
#include <stdio.h>
void for_each(int * arr, int size, void (*fun)(int))
{
for (int i = 0; i < size; i++)
{
(*fun)(arr[i]);
}
}
void print_num(int num)
{
printf("%d\n", num);
}
int main()
{
int array [] = {1, 2, 3, 4};
for_each(array, 4, print_num);
return 0;
}
Use a function pointer, like this:
#include <stdio.h>
void for_each_function(int* arr, size_t size, void(*fun)(int)) {
for(size_t i = 0; i < size; ++i)
(*fun)(arr[i]);
}
void print_number(int);
int main(void) {
int array[] = { 1, 2, 3, 4 };
for_each_function(array, 4, &print_number);
return 0;
}
void print_number(int num)
{
printf("%d\n", num);
}
Output:
1
2
3
4
Remarks:
The third parameter of for_each_function, namely void(*fun)(int),
is a function pointer named fun, with a return type void, and a
parameter of type int.
Inside the for each body, you call the function pointer like this
(*fun)(arr[i]);, which dereferences the function pointer fun, and
would pass arr[i] as its parameter. You could also use fun(arr[i]).
In the call of the for each function in main function, you need to
use the address of the function you want to point to, like this
for_each_function(array, 4, &print_number);. You could also use for_each_function(array, 4, print_number);.
PS: In your example array, I don't think you wanted to use NULL as the last element (you would probably get a warning like warning: initialization of 'int' from 'void *' makes integer from pointer without a cast [-Wint-conversion], unless NULL was defined as 0, as commented by #EricPostpischil), so I got rid of it in my example.
A modification of the answer of davidlowryduda / gsamaras to be compatible with any type of array, not just int, however that impacts the called function which gets a pointer rather than a value :
#include <stdio.h>
void for_each(void * arr, size_t nElts, size_t sizeElt, void (*fun)(void *))
{
char * p = arr;
for (size_t i = 0; i < nElts; i++)
{
(*fun)(p);
p += sizeElt;
}
}
/* for_each can be called directly or via the following macro,
the array can be an expression without any problem : is it given
in argument and the other uses are only for sizeof */
#define FOR_EACH(a, f) for_each(a, sizeof(a)/sizeof(*a), sizeof(*a), f)
void print_int(void * p)
{
printf("%d\n", *((int *) p));
}
void print_short(void * p)
{
printf("%d\n", *((short *) p));
}
int main()
{
int iarray [] = {1, 2, 3, 4};
FOR_EACH(iarray, print_int); /* for_each(iarray, sizeof(iarray)/sizeof(*iarray), sizeof(*iarray), print_int); */
short sarray [] = {5, 6, 7, 8};
FOR_EACH(sarray, print_short); /* for_each(sarray, sizeof(sarray)/sizeof(*sarray), sizeof(*sarray), print_short); */
return 0;
}
Compilation and execution:
pi#raspberrypi:~ $ gcc -pedantic -Wall -Wextra i.c
pi#raspberrypi:~ $ ./a.out
1
2
3
4
5
6
7
8
You can define a macro for this.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FOR_EACH(type, target, size, body) \
\
for (size_t i = 0; i < size; i++) \
{ \
type value = target[i]; \
body; \
}
int main(int argc, char const *argv[])
{
int arr[4] = {0, 1, 2, 3};
char *name = "My Name";
FOR_EACH(int, arr, 4, {
printf("%d\n", value);
})
size_t len = strlen(name);
FOR_EACH(char, name, len, {
printf("%c-", value);
})
return 0;
}
In this case you don't even need a function and it can be used to iterate over any array of any type as long as you know its length.
You could do something like that using function pointers. But using macros would be very more powerful, it will allow your foreach to be generic.
#include <stdio.h>
typedef struct int_array{
int *data;
int len;
}Int_array;
void print_number(int num)
{
printf("%d\n", num);
}
void for_each_function(Int_array a, void (*f)(int)){
for(int i =0; i < a.len;i++){
(*f)(a.data[i]);
}
}
int main(){
int data[4] = { 1, 2, 3, 4 };
Int_array x;
x.len = 4;
x.data = data;
for_each_function(x, print_number);
}
I took a solution's friend on forum and I increased.
I got the idea that foreach doesn't have to have a value to stop the loop.
#include <iostream>
#include <stdio.h>
void for_each(int * arr, void (*fun)(int)){
for (int i = 0; i < arr[i]; i++){
(*fun)(arr[i]);
}
}
void print_num(int num){
printf("%d\n", num);
}
int main(){
int array [] = {1, 2, 3, 4, 5, 6};
for_each(array, print_num);
}

Length of 2D array[i]

I'm working in C, and am attempting to replicate the length member function that other languages (ie: C++) use to determine the length of an array or possibly vector of data. Is this something I can accomplish in C, or do I have to fall back onto examples like this:
int arraySize = sizeof(array) / sizeof(array[0]);
In general, in C, you use arrays as they are: a contiguous set of multiple pieces of data of the same type. You are generally expected to keep track of array sizes, along with the size of individual members, yourself.
In C++, for example, you have access to the Vector class, which encapsulates and handles all this record keeping for you.
In C, you would be expected to know exactly how big the array is. This is especially important in the case of pointer decay. Your initial example...
int arrayOfInts[6] = {1, 2, 3, 4, 5, 6};
int sizeOfArray = sizeof(arrayOfInts) / sizeof(int); // Success; Returns "6"
This works in this case, but it will fail if you were to pass the array to a function expecting an array of integers (as a pointer) as a function argument.
#include <stdio.h>
int getArraySize(int* arr);
int main(void) {
int arrayOfInts[6] = {1, 2, 3, 4, 5, 6};
int sizeOfArray = getArraySize(arrayOfInts);
return 0;
}
int getArraySize(int* arr) {
int ret;
ret = sizeof(arr) / sizeof(int); // FAILS, returns the size of a pointer-to-int, not the size of the array
return ret;
}
There are two ways to handle this: static definitions, or careful dynamic memory management.
// CASE 1: Trivial case, all arrays are of a static fixed size
#include <stdio.h>
#define ARR_SIZE (6)
int getArraySize(int* arr);
int main(void) {
int arrayOfInts[ARR_SIZE] = {1, 2, 3, 4, 5, 6};
int sizeOfArray = getArraySize(arrayOfInts);
return 0;
}
int getArraySize(int* arr) {
return ret ARR_SIZE;
}
// CASE 2: Managing sizes with dynamic allocation
#include <stdio.h>
#define ARR_SIZE (6)
int main(void) {
int sizeOfArray = ARR_SIZE;
int* arrayOfInts = malloc(sizeOfArray*sizeof(int));
if (arrayOfInts != NULL) {
// Success; initialize
int i;
for (i=0; i<sizeOfArray; i++) {
arrayOfInts[i] = i;
}
return 0;
} else {
// Failed; abort
sizeOfArray = 0;
return (-1);
}
}

C pass int array pointer as parameter into a function

I want to pass the B int array pointer into func function and be able to change it from there and then view the changes in main function
#include <stdio.h>
int func(int *B[10]){
}
int main(void){
int *B[10];
func(&B);
return 0;
}
the above code gives me some errors:
In function 'main':|
warning: passing argument 1 of 'func' from incompatible pointer type [enabled by default]|
note: expected 'int **' but argument is of type 'int * (*)[10]'|
EDIT:
new code:
#include <stdio.h>
int func(int *B){
*B[0] = 5;
}
int main(void){
int B[10] = {NULL};
printf("b[0] = %d\n\n", B[0]);
func(B);
printf("b[0] = %d\n\n", B[0]);
return 0;
}
now i get these errors:
||In function 'func':|
|4|error: invalid type argument of unary '*' (have 'int')|
||In function 'main':|
|9|warning: initialization makes integer from pointer without a cast [enabled by default]|
|9|warning: (near initialization for 'B[0]') [enabled by default]|
||=== Build finished: 1 errors, 2 warnings ===|
In your new code,
int func(int *B){
*B[0] = 5;
}
B is a pointer to int, thus B[0] is an int, and you can't dereference an int. Just remove the *,
int func(int *B){
B[0] = 5;
}
and it works.
In the initialisation
int B[10] = {NULL};
you are initialising anint with a void* (NULL). Since there is a valid conversion from void* to int, that works, but it is not quite kosher, because the conversion is implementation defined, and usually indicates a mistake by the programmer, hence the compiler warns about it.
int B[10] = {0};
is the proper way to 0-initialise an int[10].
Maybe you were trying to do this?
#include <stdio.h>
int func(int * B){
/* B + OFFSET = 5 () You are pointing to the same region as B[OFFSET] */
*(B + 2) = 5;
}
int main(void) {
int B[10];
func(B);
/* Let's say you edited only 2 and you want to show it. */
printf("b[0] = %d\n\n", B[2]);
return 0;
}
If you actually want to pass an array pointer, it's
#include <stdio.h>
void func(int (*B)[10]){ // ptr to array of 10 ints.
(*B)[0] = 5; // note, *B[0] means *(B[0])
//B[0][0] = 5; // same, but could be misleading here; see below.
}
int main(void){
int B[10] = {0}; // not NULL, which is for pointers.
printf("b[0] = %d\n\n", B[0]);
func(&B); // &B is ptr to arry of 10 ints.
printf("b[0] = %d\n\n", B[0]);
return 0;
}
But as mentioned in other answers, it's not that common to do this. Usually a pointer-to-array is passed only when you want to pass a 2d array, where it suddenly looks a lot clearer, as below. A 2D array is actually passed as a pointer to its first row.
void func( int B[5][10] ) // this func is actually the same as the one above!
{
B[0][0] = 5;
}
int main(void){
int Ar2D[5][10];
func(Ar2D); // same as func( &Ar2D[0] )
}
The parameter of func may be declared as int B[5][10], int B[][10], int (*B)[10], all are equivalent as parameter types.
Addendum: you can return a pointer-to-array from a function, but the syntax to declare the function is very awkward, the [10] part of the type has to go after the parameter list:
int MyArr[5][10];
int MyRow[10];
int (*select_myarr_row( int i ))[10] { // yes, really
return (i>=0 && i<5)? &MyArr[i] : &MyRow;
}
This is usually done as below, to avoid eyestrain:
typedef int (*pa10int)[10];
pa10int select_myarr_row( int i ) {
return (i>=0 && i<5)? &MyArr[i] : &MyRow;
}
In new code assignment should be,
B[0] = 5
In func(B), you are just passing address of the pointer which is pointing to array B. You can do change in func() as B[i] or *(B + i). Where i is the index of the array.
In the first code the declaration says,
int *B[10]
says that B is an array of 10 elements, each element of which is a pointer to a int. That is, B[i] is a int pointer and *B[i] is the integer it points to the first integer of the i-th saved text line.
Make use of *(B) instead of *B[0].
Here, *(B+i) implies B[i] and *(B) implies B[0], that is *(B+0)=*(B)=B[0].
#include <stdio.h>
int func(int *B){
*B = 5;
// if you want to modify ith index element in the array just do *(B+i)=<value>
}
int main(void){
int B[10] = {};
printf("b[0] = %d\n\n", B[0]);
func(B);
printf("b[0] = %d\n\n", B[0]);
return 0;
}
main()
{
int *arr[5];
int i=31, j=5, k=19, l=71, m;
arr[0]=&i;
arr[1]=&j;
arr[2]=&k;
arr[3]=&l;
arr[4]=&m;
for(m=0; m<=4; m++)
{
printf("%d",*(arr[m]));
}
return 0;
}
Using the really excellent example from Greggo, I got this to work as a bubble sort with passing an array as a pointer and doing a simple -1 manipulation.
#include<stdio.h>
void sub_one(int (*arr)[7])
{
int i;
for(i=0;i<7;i++)
{
(*arr)[i] -= 1 ; // subtract 1 from each point
printf("%i\n", (*arr)[i]);
}
}
int main()
{
int a[]= { 180, 185, 190, 175, 200, 180, 181};
int pos, j, i;
int n=7;
int temp;
for (pos =0; pos < 7; pos ++){
printf("\nPosition=%i Value=%i", pos, a[pos]);
}
for(i=1;i<=n-1;i++){
temp=a[i];
j=i-1;
while((temp<a[j])&&(j>=0)) // while selected # less than a[j] and not j isn't 0
{
a[j+1]=a[j]; //moves element forward
j=j-1;
}
a[j+1]=temp; //insert element in proper place
}
printf("\nSorted list is as follows:\n");
for(i=0;i<n;i++)
{
printf("%d\n",a[i]);
}
printf("\nmedian = %d\n", a[3]);
sub_one(&a);
return 0;
}
I need to read up on how to encapsulate pointers because that threw me off.
The argument of func is accepting double-pointer variable.
Hope this helps...
#include <stdio.h>
int func(int **B){
}
int main(void){
int *B[10];
func(B);
return 0;
}
In the function declaration you have to type as
VOID FUN(INT *a[]);
/*HERE YOU CAN TAKE ANY FUNCTION RETURN TYPE HERE I CAN TAKE VOID AS THE FUNCTION RETURN TYPE FOR THE FUNCTION FUN*/
//IN THE FUNCTION HEADER WE CAN WRITE AS FOLLOWS
void fun(int *a[])
//in the function body we can use as
a[i]=var

Why is this array notation illegal in C?

If this is possible:
#include <stdio.h>
#include <process.h>
#define SIZE 5
void PassingArray(int arr[])
{
int i=0;
for(i=0 ; i<SIZE ; i++)
{
printf("%d, ", arr[i]);
}
printf("\n");
}
main()
{
int myIntArray[5] = {1, 2, 3, 4, 5};
PassingArray(myIntArray);
system("PAUSE");
}
Then why the following is illegal?
#include <stdio.h>
#include <process.h>
#define SIZE 5
int ReturningArray()[]
{
int myIntArray[5] = {1, 2, 3, 4, 5};
return myIntArray;
}
main()
{
int myArray[] = ReturningArray();
system("PAUSE");
}
You're not returning an int, but you're returning the array. This is the same value as &myIntArray[0]. int ReturningArray()[] is not a valid function prototype.
There's multiple reasons why this doesn't work.
The first is simply that it's prohibited by the language - the return type of a function shall not be an array (it also can't be a function).
The second is that even if you were allowed to declare ReturningArray as you do, you could never write a valid return statement in that function - an expression with array type that is not the subject of the unary & or sizeof operators evaluates to a pointer to the first element of the array, which no longer has array type. So you can't actually make return see an array.
Thirdly, even if we somehow had a function returning an array type, you couldn't use that return value as the initialiser of an array variable - the return value would again evaluate to a pointer to the first element of the array: in this case a pointer to int, and a pointer to int isn't a suitable initialiser for an array of int.
There are several problems with this code.
You are placing the brackets at the wrong place. Instead of
int ReturningArray()[]
it should be
int* ReturningArray()
You are returning a local variable. Local variables only exist during the execution of the function and will be removed afterwards.
In order to make this work you will have to malloc the int array and return the pointer to the array:
#include <stdio.h>
#include <malloc.h>
#define SIZE 5
int* ReturningArray()
{
int *myIntArray = (int *)malloc(SIZE * sizeof(int));
myIntArray[0] = 1;
myIntArray[1] = 2;
myIntArray[2] = 3;
myIntArray[3] = 4;
myIntArray[4] = 5;
return myIntArray;
}
int main(void)
{
int i;
int* myArray = ReturningArray();
for(i=0;i<SIZE;i++) {
printf("%d\n", myArray[i]);
}
free(myArray); // free the memory again
system("PAUSE");
return 0;
}
PassingArray is legal, but it does not pass an array. It passes a pointer to the first element of an array. void PassingArray(int arr[]) is a confusing synonym for void PassingArray(int *arr). You can't pass an array by value in C.
ReturningArray is not allowed, you can't return an array by value in C either. The usual workaround is to return a struct containing an array:
typedef struct ReturnArray {
int contents[5];
} ReturnArray;
ReturnArray ReturningArray()
{
ReturnArray x = {{1, 2, 3, 4, 5}};
return x;
}
Arrays are second-class citizens in C, the fact that they can't be passed or returned by value is historically related to the fact that they can't be copied by assignment. And as far as I know, the reason for that is buried in the early development of C, long before it was standardized, when it wasn't quite decided how arrays were going to work.
You can't return array from a function, but It is possible that you can declare a function returning a (reference in C++) or pointer to array as follows:
int myIntArray[] = {1, 2, 3, 4, 5};
int (*ReturningArray())[sizeof(myIntArray)/sizeof(int)] {
return &myIntArray;
}

Resources