What does something like int *array[99] = {0}, *u do? - c

bool checkSubarraySum(int* nums, int numsSize, int k) {
int i, s, found = 0;
e_t buff[10000];
int n;
e_t *set[SZ] = { 0 }, *e;
put(set, &buff[n ++], 0, -1);
s = 0;
for (i = 0; i < numsSize; i ++) {
s += nums[i];
if (k) s = s % k;
e = lookup(set, s);
if (e) {
if (i - e->idx >= 2) {
found = 1;
break;
}
} else {
put(set, &buff[n ++], s, i);
}
}
return found;
}
What is e_t *set[SZ] = { 0 }, *e; doing? e_t is a user defined type but I don't think that matters. e is not a pointer that has been defined anywhere in global scope to my knowledge, and I tried something like the following:
int *array[5] = {0}, *u;
and no syntax errors were given. The first part, i.e. int *array[5] = {0} initializes all five elements of this array to 0. But what is the purpose of *u? You can't just assign an array to something else, right, it's an address, not a pointer. And u has never even been defined, so, I would expect some sort of NameError...
Thanks for any help in advance.

It is similar to typing:
int x, y;
but notice the types when typing something like:
int a, *b, **c;
/* ^ ^ ^
* int int* int**
*/
therefore
int *array[5] = {0}, *u;
/* ^ is pointer to int */

int *array[5] = {0}, *u;
Is a declaration of two int objects. The first:
int *array[5] = {0}
declares an array-of-pointers to int [5] (meaning an array of 5 pointers to int) initialized to NULL by virtue of using the "universal initializer" {0}. The equivalent, but more intuitive initialization would be:
int *array[5] = {NULL}
The ',' is simply a separator here that allows the second declaration *u to be included in the same line without a separate int *u; declaration.
(not to be confused with the comma-operator that simply discards expressions to the left of the final ',' evaluating the last expression. See What does the comma operator , do? -- thank you #AnttiHaapala)
So:
..., *u;
declares a single (uninitialized) pointer-to int.

e_t *set[SZ] = { 0 }, *e;
is a declaration of two objects; set is an array of pointers to e_t, while e is a pointer to a single e_t. It may also be written as:
e_t *set[SZ] = {0};
e_t *e;

e_t *set[SZ] = { 0 }, *e; should be read as "the programmer hereby declares that the following are of type e_t: the objects pointed to by each SZ elements in set; and the object pointed to by e."
= {0} causes each element in set to be initialized to null pointers - the first explicitly and the remaining implicitly.

Related

Can we initiate an array literal with variables in C?

I have been searching if we can initiate an array literal with variables but couldn't find it. Bit of context, I want to pass an array literal to a function. Below is what I am trying to do:
int fun(int * a, int num){
int sum=0;
for (int i=0; i< num; ++i){
sum = sum + a[i];
}
return sum;
}
int main(){
int a = 3, b =2, c = 1 ;
int x[3] = {a,b,c}; // Is this legal? It compiles fine on all compilers I tested.
int p = fun( (int[3]){a,b,c} , 3); // I want to do something like this. pass a literal to the fucntion
return 0;
}
From the C Standard (6.7.9 Initialization)
4 All the expressions in an initializer for an object that has static
or thread storage duration shall be constant expressions or string
literals.
The string literal defined in this record
int p = fun( (int[3]){a,b,c} , 3);
has automatic storage duration. So you may initialize it with non-constant expressions in particularly using the variables a, b, and c.
Pay attention to that as the function does not change the passed array then the first parameter should have the qualifier const and to avoid overflow it is better to declare the return type as long long int.
Here is a demonstration program.
#include <stdio.h>
long long int fun( const int * a, size_t n )
{
long long int sum = 0;
for ( size_t i = 0; i < n; ++i )
{
sum += a[i];
}
return sum;
}
int main( void )
{
int a = 3, b = 2, c = 1 ;
printf( "%lld\n", fun( ( int[] ){a, b, c} , 3 ) );
}
Your code (sans the extra x array) compiles just fine with -std=c99 so yes, I'd say it's standard C99 code.
#include <stdio.h>
int fun(int a[], int num) {
int sum = 0;
for (int i = 0; i < num; ++i) {
sum = sum + a[i];
}
return sum;
}
int main() {
int a = 3, b = 2, c = 1;
int p = fun((int[3]){a, b, c}, 3);
printf("%d", p);
return 0;
}
This would not be allowed if the initializer is static, since the value needs to be assigned before the program executes. From C99:
All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
Otherwise, each initializer needs to be an "assignment-expression" or, in other words, a valid expression that can be assigned to an object.
So yes, this is legal in C.
Well, yes. The array is being initialized as it should which can be tested by printing it.
The array is also being sent to the function properly as p returns 6. However, do note that you are making a new array to send to the function.

C incomplete Type in structs

He folks,
i got a problem and a question.
Hopefully u can help and explain me.
first of all i have 2 stucts:
typedef struct {
double x;
double y;
} A;
typedef struct {
unsigned int count;
A(*stack)[];
}B;
this struct B i declare in main() and passing a Pointer of B to a function this will initializ
main(){
B x;
function rr(&x);
}
void rr(B* test) {
test->stack= malloc((4) * sizeof(A)); //4Elements
for (unsigned int i = 0; i < 4; i++) {
(test->stack+ i)->x= 89;
}
}
on this line
(test->stack+ i)->x= 89;
compiler says incomplete Type
i know why it is incomplete cause in struct B their is no dimension.
but array should initialize in function rr
Maybe u understand what i mean and how to solve my problem.
function rr i am not allowed to change.
Greetings
EDIT 1
Thank you for all answers
mabey i schould clearify my problem
typedef struct {
unsigned int count;
A(*stack)[]; // here i want a pointer to an array of A's
}B;
//over main it is declared
void rr(B*);
main(){
B x;
function rr(&x);
}
// this func is not allowed to change
void rr(B* test) {
test->stack= malloc((4) * sizeof(A)); //4Elements
for (unsigned int i = 0; i < 4; i++) {
(test->stack+ i)->x= 89; // error cause incomplete type but i
//have to use this line
}
}
Hope now it is easier to i understand what i want
This declaration:
A(*stack)[];
Says that stack is a pointer to an array of A of unknown size. That is an incomplete type which means it can't be used directly.
It seems like what you actually want is not a pointer to an array, but a pointer to the first member of a dynamic array of A. So declare the member as a pointer:
A *stack;
In the expression:
(test->stack+ i)->x= 89;
before accessing an array via a pointer to an array you must dereference it.
Try:
(*test->stack)[i].x= 89;
You do not know how to use flexible array members.
Simply:
typedef struct {
double x;
double y;
} A;
typedef struct {
size_t count;
A stack[];
}B;
B *createStack(size_t size)
{
B *s = malloc(sizeof(*s) + size * sizeof( s -> stack[0]));
return s;
}
void rr(B* test) {
for (unsigned int i = 0; i < 4; i++) {
(test->stack+ i)->x= 89;
}
}
int main(void)
{
B *stack = createStack(4);
rr(stack);
free(stack);
}
You need only one allocation to mallloc/realloc or free the structure. The array will decay into pointer for your assignment in rr function.

How to declare, define, and call a functions in C program which have to 1)"fill" the 3D-array and 2)"read" the 3D-array of characters

I am a novice in C-programming and I need help from anyone who is familiar with 3D-arrays and can perform some changes on them by functions.
All explanations, which I found on net, based on 2D-arrays. I can't understand them.
I mean, I understand the basics of pointers, function prototypes(declarations), function definitions, and how to operate with 1D-arrays of data.
I know that any function call can make a local copy or change a variable data in its physical storage, but I can't understand one thing. When you call function with char * type parameter(array), you always type it like — void func_name(char * var_name) — so, if you need to change the value, you type it in just like that, and when you have not to change — you add const before char * var_name.
For parameters of int and char-types we have another rule: you have to add (de?)reference operator - * - in func prototype and its definition, if you want to change the variable data in storage, and you don't have to use it if there's no need of changing("take local copy" command); and, you have to call a func with dereference operator &, applied to parameter — for example void func_name(&var_name); , if you have to change the variable data.
Could you please explain how to behave properly when my task is to operate with 3D-arrays by specific functions — "fill the first dimension", "fill the 3rd dimension" "read Nth dimension(local copy)"-commands? How I have to write function prototypes to change and not to change the value of 3D-array?
void func_name(char *array[][][]) — is that correct?
void func_name( char *(***array) ) — or maybe like that?
If I have to operate with elements in EACH dimension, do I have to prototype functions like this? :
void func_name( char *(*array), char *(**array), char *(***array) ) {. . .}
Is there any specific rules for calling 3D-array-operating functions? Or I just have to leave them like func_name(var_name); ?
I've found some working code, which try to explain how to define a function with 2d-array as a parameter in it and how to call this function which just "reads" the 2d-array(takes local copy).
But this code doesn't make it clear for me how to perform another operation("fill") with functions and how to write prototype properly. And, the example has only operations with int-type, but I need char *..
The code:
#include <stdio.h>
const int M = 3;
const int N = 3;
void print(int arr[M][N])
{
int i, j;
for (i = 0; i < M; i++)
for (j = 0; j < N; j++)
printf("%d ", arr[i][j]);
}
int main()
{
int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
print(arr);
char answer[10];
printf("ok? : ");
scanf("%s", answer);
return 0;
}
And finally, I can't understand clearly what does these phrases mean: "2d-array of pointers to characters" , "Pointer to 2D-array of characters" ; and I can't understand contexts, where to use "array of pointers" and where to use "pointer to array".
The mess in my head is grown from the fact, that in function prototypes and definitions we use (type-name) * as a type always with array as a function argument.
There are a lot of questions, so I will appreciate any help, thanks!
EDIT 1:
Guys, I've poked around for a while and got some working compilation, which resolves my task. Thanks everyone for the feedback, my solution is below.
Solution:
#include <stdio.h>
void find(int a, char *name, char *country, char *city, const char (*paaa)[4][100]);
void fill( char (*paaa)[4][100] );
// --------------------------------------------//
int main()
{
char name[100] = {0}, country[50] = {0}, city[50] = {0};
char array3D[100][4][100]; // 0 field is for name, 1 - for city, 2 - for country
char (*paaa)[4][100] = &array3D[0]; // initialize the pointer 'paaa'
fill(paaa); // fills 12 entries with the same data in each field
printf("> full array: \n");
printf("\033[0;34m"); // set text color to blue
for (int x = 0; x < 12*4; x++) // each entry contains 4 fields of strings, so '12*4' here
{
printf("%s", (*paaa)[x]);
}
printf("\033[0m"); // reset text color to default
int a = 0;
printf("> input entry number(max:11): ");
scanf("%u", &a);
printf("\n");
find(a, name, country, city, paaa); // retrieve each field in variables
printf("ENTRY No. %u : \n\n", a);
printf("> Name - %s\n", name);
printf("> City - %s\n", city);
printf("> Country - %s\n", country);
printf("> Good? : ");
scanf("%u", &a);
printf("> Done.\n\n");
return 0;
}
// --------------------------------------------//
void fill( char (*paaa)[4][100] )
{
char local_name[50] = { " Jacob Goodman \n" };
char local_city[50] = { " Melbourne \n" };
char local_country[50] = { " Australia \n" };
int entries_amount = 12;
int en = 0, da = 0; //entry, data
for (en = 0; en < entries_amount ; en++)
{
for ( da = 0; local_name[da] != '\0'; da++)
{
paaa[en][0][da] = local_name[da];
}
for ( da = 0; local_city[da] != '\0'; da++)
{
paaa[en][1][da] = local_city[da];
}
for ( da = 0; local_country[da] != '\0'; da++)
{
paaa[en][2][da] = local_country[da];
}
}
}
// takes an entry number,
// reads from 3D-array 3 fields of given entry
// and saves each field to 3 global variables
void find(int a, char *name, char *city, char *country, const char (*paaa)[4][100])
{
int da = 0;
for ( da = 0; paaa[a][0][da] != '\0'; da++)
{
name[da] = paaa[a][0][da];
}
for ( da = 0; paaa[a][1][da] != '\0'; da++)
{
city[da] = paaa[a][1][da];
}
for ( da = 0; paaa[a][2][da] != '\0'; da++)
{
country[da] = paaa[a][2][da];
}
}
A "pointer to T" can be used to point to a single T variable or to point to the first element of an array of T. All elements of the array of T can be accessed via the pointer.
T a;
T arr[3]; // Array [3] of T
T *pa = &a; // Pointer to T
T *parr = &arr[0]; // Pointer to T. Equivalent initializer: T *parr = arr;
*pa = foo; // will set a = foo;
parr[2] = bar; // will set arr[2] = bar;
pa and parr are both of type "pointer to T".
A "2-D array of T" is an "array of array of T":
T aa[4][3]; // Array [4] of array [3] of T
aa[0][1] = foo;
An "array of pointers to T" can be used to mimic a 2-D array of T. Each pointer element points to its own array of T which could be dynamically allocated as below:
T *ad[4]; // Array [4] of pointer to T
for (i = 0; i < 4; i++) {
ad[i] = calloc(3, sizeof (T));
}
ad[0][1] = foo;
A "pointer to an array of T" can be used to access elements of a 2-D array of T:
T aa[4][3]; // Array [4] of array [3] of T
T (*paa)[3] = aa; // Pointer to array [3] of T. Equivalent initializer: T (*paa)[3] = &aa[0];
paa[0][1] = foo; // will set aa[0][1] = foo;
A "pointer to pointer to T" can be used to access the elements of an "array of pointer to T":
T arow0[3], arow1[3], arow2[3], arow3[3]; // Each is array [3] of T
T *ad[4] = {arow0, arow1, arow2, arow3}; // Array [4] of pointer to T
T **pad = &ad[0]; // Pointer to pointer to T. Equivalent initializer: T **pad = ad;
pad[0][1] = foo; // will set ad[0][1] = foo; will set arow0[1] = foo;
A "3-D array of T" is an "array of array of array of T":
T aaa[4][3][2]; // Array [4] of array [3] of array [2] of T
A "pointer to 2-D array of T" is a "pointer to array of array of T", and can be used to access the elements of a 3-D array of T (of compatible dimensions):
T aaa[4][3][2]; // Array [4] of array [3] of array [2] of T
T (*paaa)[3][2]; // Pointer to array [3] of array [2] of T
paaa = aaa; // Equivalent: paaa = &aaa[0];
paaa[0][1][1] = foo; // will set aaa[0][1][[1] = foo;
A "2-D array of pointers to T" is an "array of array of pointers to T":
T arow00[2], arow01[2], arow02[2]; // Each is array [2] of T
T arow10[2], arow11[2], arow12[2];
T arow20[2], arow21[2], arow22[2];
T arow30[2], arow31[2], arow32[2];
T *app[4][3] = {
{arow00, arow01, arow02},
{arow10, arow11, arow12},
{arow20, arow21, arow22},
{arow30, arow31, arow32}
}; // Array [4] of array [3] of pointer to T
app[0][1][1] = foo; // Will set arow01[1] = foo;
A "pointer to pointer to pointer to T" can be used to access the elements of an array of pointers to pointers to T:
T arow00[2], arow01[2], arow02[2]; // Each is array [2] of T
T arow10[2], arow11[2], arow12[2];
T arow20[2], arow21[2], arow22[2];
T arow30[2], arow31[2], arow32[2];
T *parow0[3] = { arow00, arow01, arow02 }; // Each is array [3] of pointer to T
T *parow1[3] = { arow10, arow11, arow12 };
T *parow2[3] = { arow20, arow21, arow22 };
T *parow3[3] = { arow30, arow31, arow32 };
T **ppa[4] = { parow0, parow1, parow2, parow3 }; // Array [4] of pointer to pointer to T
T ***pppa = ppa; // Pointer to pointer to pointer to T;
pppa[0][1][1] = foo;
// will set ppa[0][1][1] = foo;
// will set parow0[1][1] = foo;
// will set arow01[1] = foo;
I would like to first leave this whole mess of questions and concentrate on the task you want to do.
You have given several examples for operations with functions, to operate with an three-dimensional array. I will choose the option to fill an array with values by the use of scanf() as example.
What i would do is just give a pointer to the 3D array as function argument.
The declaration/prototype for this function would be:
void fill(char *p);
Furthermore, i would increase that pointer inside the function, plus use this increased pointer in loops to fill all elements:
#include <stdio.h>
const int M = 3;
const int N = 3;
int main(void)
{
char a[M][N];
fill(a);
return 0;
}
void fill(char *p)
{
int i,j;
for(i = 0, j = 0; i < ( M * N ); i++,j++)
{
if(j == M)
{
printf("\n");
j = 0;
}
scanf("%c",(p + i));
}
}
For the other questions, I would recommend that you ask separate questions for each to get more answers and to get an answer which is most appropriate for its special case.
Ian Abbott's answer is good. To summarize a bit, an array name is a pointer to the first member, as always. But only for one dimension. So int a[10] is an array of int and becomes a pointer to int, written int *. The array int a[10][20] is an array of ten arrays of 20 int. It becomes a pointer to an array of 20 int, written int (*)[20], but not pointer to pointer to int.
You also cannot leave out the extra sizes. They are part of the type. If you need to be able to write a function which takes any three-dimensional array, you're sunk. You can use C++ and make a template. In plain C, the usual is to declare your array as single-dimension and impose any dimensional structure by doing your own subscript arithmetic.

what's the difference between int (* f [])(); and int f[]();

i find this in Pointers on C
int f[](); /* this one is illegal */
and:
int (* f [])(); /* this one legal. */
i really want know what's the usage of the second one.
thank you.
The second example is quite valid, if you use initialization block. For example:
#include <stdio.h>
int x = 0;
int a() { return x++ + 1; }
int b() { return x++ + 2; }
int c() { return x++ + 3; }
int main()
{
int (* abc[])() = {&a, &b, &c};
int i = 0,
l = sizeof(abc)/sizeof(abc[0]);
for (; i < l; i++) {
printf("Give me a %d for %d!\n", (*abc[i])(), i);
}
return 0;
}
I'm not sure if the second example is legal, since the size of the function array is not known, but what it is supposed to be is an array of function pointers, and here is a possible example of usage if the size would be known:
int a()
{
return 0;
}
int main(int argc ,char** argv)
{
int (* f [1])();
f[0] = a;
}
int f[](); // this is illegal because of you can't create array of functions . It's illegal in C
But second is legal
int (* f [])(); It says that f is an array of function pointers returning int and taking unspecified number of arguments
int f[](); /* this one is illegal */
That's trying to declare an array of functions, which is impossible.
int (* f [])(); /* this one NOT legal, despite what the OP's post says. */
That's trying to declare an array of function pointers, which would be perfectly legal (and sensible) if the array size were specified, e.g.:
int (* f [42])(); /* this one legal. */
EDIT: The type int (* f [])() can be used as a function parameter type, because for function parameter types, array-to-pointer conversion takes place immediately, meaning we don't ever need to specify the dimension of the innermost array of a (possibly multidimensional) array:
void some_func(int (* f [])()); /* This is also legal. */

C: Copy array without knowing its type

I have function, it receive pointer to array and pointer to function and should return new array with order defined by function passed in parameter.
My problem how I copy element of one array to another without knowing its type
void * scrambleArr(void * arr, int numElem, int elemSize, int (*func)(void*)) {
void * newArr;
int cPos, newPos,i;
newArr = (void *)malloc(numElem*elemSize);
for (i=0 ; i < numElem ; i++)
{
cPos = i*elemSize;
newPos = func((char*)arr+cPos);
*((char*)newArr+newPos) = *((char*)arr+cPos);
}
return newArr;
}
Function that passed in the last parameter
int posArrayBySize(void *el) {
ARRAY* arr = (ARRAY *)el;
return arr->size - 1;
}
And code in main:
int main( ) {
ARRAY * arrSorted;
int a[2] = {1,2};
int b[3] = {1,1,1};
int c[1] = {9};
int d[4] = {3,3,3,3};
ARRAY arr[4] = {{a,2},{b,3},{c,1},{d,4}};
arrSorted =(ARRAY *)scrambleArr(arr,4,sizeof(ARRAY),posArrayBySize);
free(arrSorted);
return 0;
}
After running arrSorted contain garbage,
Can someone point me, what i miss?
Another option for me is not to copy, just to point one array to elements of other, is it possible?
Thanks.
memcpy is the function you are looking for.
This won't work
*((char*)newArr+newPos) = *((char*)arr+cPos);
because you're dereferencing arr+cPos as it is char, so it will copy only the first byte.

Resources