What does (int (*)[])var1 stand for? - c

I found this example code and I tried to google what (int (*)[])var1 could stand for, but I got no usefull results.
#include <unistd.h>
#include <stdlib.h>
int i(int n,int m,int var1[n][m]) {
return var1[0][0];
}
int example() {
int *var1 = malloc(100);
return i(10,10,(int (*)[])var1);
}
Normally I work with VLAs in C99 so I am used to:
#include <unistd.h>
#include <stdlib.h>
int i(int n,int m,int var1[n][m]) {
return var1[0][0];
}
int example() {
int var1[10][10];
return i(10,10,var1);
}
Thanks!

It means "cast var1 into pointer to array of int".

It's a typecast to a pointer that points to an array of int.

(int (*)[]) is a pointer to an array of ints. Equivalent to the int[n][m] function argument.
This is a common idiom in C: first do a malloc to reserve memory, then cast it to the desired type.

Related

How to define functions inside an array in C? [duplicate]

I have a struct that contains a declaration like this one:
void (*functions[256])(void) //Array of 256 functions without arguments and return value
And in another function I want to define it, but there are 256 functions!
I could do something like this:
struct.functions[0] = function0;
struct.functions[1] = function1;
struct.functions[2] = function2;
And so on, but this is too tiring, my question is there some way to do something like this?
struct.functions = { function0, function1, function2, function3, ..., };
EDIT: Syntax error corrected as said by Chris Lutz.
I have a struct that contains a declaration like this one:
No you don't. That's a syntax error. You're looking for:
void (*functions[256])();
Which is an array of function pointers. Note, however, that void func() isn't a "function that takes no arguments and returns nothing." It is a function that takes unspecified numbers or types of arguments and returns nothing. If you want "no arguments" you need this:
void (*functions[256])(void);
In C++, void func() does mean "takes no arguments," which causes some confusion (especially since the functionality C specifies for void func() is of dubious value.)
Either way, you should typedef your function pointer. It'll make the code infinitely easier to understand, and you'll only have one chance (at the typedef) to get the syntax wrong:
typedef void (*func_type)(void);
// ...
func_type functions[256];
Anyway, you can't assign to an array, but you can initialize an array and copy the data:
static func_type functions[256] = { /* initializer */ };
memcpy(mystruct.functions, functions, sizeof(functions));
I had the same problem, this is my small program to test the solution. It looks pretty straightforward so I thought I'd share it for future visitors.
#include <stdio.h>
int add(int a, int b) {
return a+b;
}
int minus(int a, int b) {
return a-b;
}
int multiply(int a, int b) {
return a*b;
}
typedef int (*f)(int, int); //declare typdef
f func[3] = {&add, &minus, &multiply}; //make array func of type f,
//the pointer to a function
int main() {
int i;
for (i = 0; i < 3; ++i) printf("%d\n", func[i](5, 4));
return 0;
}
You can do it dynamically... Here is a small example of a dynamic function array allocated with malloc...
#include <stdio.h>
#include <stdlib.h>
typedef void (*FOO_FUNC)(int x);
void a(int x)
{
printf("Function a: %d\n", x);
}
void b(int x)
{
printf("Function b: %d\n", x);
}
int main(int argc, char **argv)
{
FOO_FUNC *pFoo = (FOO_FUNC *)malloc(sizeof(FOO_FUNC) * 2);
pFoo[0] = &a;
pFoo[1] = &b;
pFoo[0](10);
pFoo[1](20);
return 0;
}
From the top of my head and untested.
// create array of pointers to functions
void (*functions[256])(void) = {&function0, &function1, &function2, ..., };
// copy pointers to struct
int i;
for (i = 0; i < 256; i++) struct.functions[i] = functions[i];
EDIT: Corrected syntax error as said by Chris Lutz.
You could do that while declaring your struct instance:
function_structur fs = { struct_field1,
struct_field2,
{function0, function1, ..., function255},
struct_field3,
... };
You cannot use this shortcut for initialize arrays after the array has been declared: if you need to do that, you'll have to do it dynamically (using a loop, a memcpy or something else).
If you want to post-initialize an array using form like {func1, func2, ...}, this can be accomplished in the following way (using GCC):
UPD (thanks to Chris Lutz for remarks)
Define a macro like this:
#define FUNCTION_VECTOR_COPY(destVec, sourceVec) memcpy(destVec, sourceVec, sizeof(sourceVec))
And pass source vector using Compound Literals, as follow:
#include <string.h>
...
void (*functions[256])();
...
FUNCTION_VECTOR_COPY (functions, ((void(*[])()) {func1, func2, func3}));

How to pass a array of strings to a function?

In the following program i just try to copy some string to the array and print it in another function.
I am getting segmentation fault .Could someone point out what i did wrong ?
#include <stdio.h>
#include <string.h>
#define MAX_STR_LEN 20
void print_str(char str[][],int count);
int main()
{
char str[2][MAX_STR_LEN];
strncpy(str[0],"hello",MAX_STR_LEN);
strncpy(str[1],"world",MAX_STR_LEN);
print_str(str,2);
return 0;
}
void print_str(char str[][],int count)
{
int i;
for(i=0;i<count;i++)
printf("%s\n",str[i]);
}
We need to specify the column size mandatory when passing a 2D array as a parameter.
So, You should declare your function like this:
void print_str(char str[][MAX_STR_LEN],int count);
Use
void print_str(char str[][MAX_STR_LEN], int count);
Provide the second dimension length in a 2-D array in C always. First dimension length is optional if you are declaring a 2-D array.

Records not updating in C because struct pointer isn't updating

This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char item[1000];
} itemset;
void additem(itemset* items,char* thing,unsigned long* numadded){
memcpy(items->item,thing,1000);
items++;(*numadded)++;
}
void showitems(itemset* items,unsigned long numitems){
itemset* p=items;
unsigned long count;
for (count=1;count<=numitems;count++){
printf("%d %s\n",count,p->item);p++;
}
}
int main(){
itemset* myitems=calloc(1,sizeof(itemset)*10);
itemset* itemstart=myitems;
unsigned long added=0;
additem(myitems,"Test",&added);
additem(myitems,"Test2",&added);
additem(myitems,"Test3",&added);
printf("Count=%d\n",added);
showitems(itemstart,added);
free(itemstart);
}
What I'm trying to see on the screen from running this code is:
Count=3
1 Test
2 Test2
3 Test3
But instead, I see:
Count=3
1 Test3
2
3
Therefore my additem function isn't working correctly. I find that a fix is to add myitems++; right after each function call, but I'm trying to make the same behavior happen inside the additem function so that I won't have to use myitems++; outside of the function. What else can I do to solve this?
Use a double pointer for items, like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char item[1000];
} itemset;
void additem(itemset** items,char* thing,unsigned long* numadded){
memcpy((**items)->item,thing,1000);
(*items)++;
(*numadded)++;
}
void showitems(itemset* items,unsigned long numitems){
itemset* p=items;
unsigned long count;
for (count=1;count<=numitems;count++){
printf("%d %s\n",count,p->item);
p++;
}
}
int main(void){
itemset* myitems=calloc(1,sizeof(itemset)*10);
itemset* itemstart=myitems;
unsigned long added=0;
additem(&myitems,"Test",&added);
additem(&myitems,"Test2",&added);
additem(&myitems,"Test3",&added);
printf("Count=%d\n",added);
showitems(itemstart,added);
free(itemstart);
return 0;
}
Output:
Count=3
1 Test
2 Test2
3 Test3
Also, check this: How to print an unsigned long int with printf in C?, which says that you should use %lu, instead of %d.
I just managed to find an answer for me that works and the guy who just answered gave a similar answer too.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char item[1000];
} itemset;
void additem(itemset** items,char* thing,unsigned long* numadded){
memcpy((**items).item,thing,1000);
(*items)++;(*numadded)++;
}
void showitems(itemset* items,unsigned long numitems){
itemset* p=items;
unsigned long count;
for (count=1;count<=numitems;count++){
printf("%d %s\n",count,p->item);p++;
}
}
int main(){
itemset* myitems=calloc(1,sizeof(itemset)*10);
itemset* itemstart=myitems;
unsigned long added=0;
additem(&myitems,"Test",&added);
additem(&myitems,"Test2",&added);
additem(&myitems,"Test3",&added);
printf("Count=%d\n",added);
showitems(itemstart,added);
free(itemstart);
}
You are over writing same pointer in add item function. You would need to pass a pointer to pointer to make it work. Also use strcpy for string copy. And for showitems pass pointer allocated in calloc call as that doesn't cahnge
You need to pass items by "reference" as well, not only numadded. Or possibly return the new pointer instead.

warning: format '%c' expects type 'int', but argument 2 has type 'char *'

I'm trying to print all characters stored in hex array to the screen, one by one, but I get this strange error in line 16. As far as I know, %c should be expecting a char, not an int.
Why I'm getting this error?
Below is my code, thanks.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <ctype.h>
#include <string.h>
int main()
{
char hex[8] = "cf0a441f";
int hexCounter;
char *currentHex;
for(hexCounter=0; hexCounter<strlen(hex); hexCounter++)
{
currentHex = &hex[hexCounter];
printf("%c",currentHex);
}
return 0;
}
You mean
printf("%c", *currentHex);
In my opinion you can remove the entire idea of currentHex since it just adds complexity for no value. Simply do:
printf("%c", hex[hexCounter]);
The important point is that you're supposed to pass the value of the character itself, not it's address which is what you're doing.
You have hex[hexCounter] as a char so when you set
currentHex = &hex[hexCounter];
you are setting currentHex to the address of a char, i.e. a char *. As such, in your printf you need
printf("%c",*currentHex);
What you are doing is unnecessary anyway, since you could just do
printf("%c",hex[hexCounter]);
currentHex should be of type char, not char *.
char currentHex;
[..]
currentHex = hex[hexCounter];
printf("%c",currentHex);
If you really want it to be a pointer, dereference it to print:
printf("%c",*currentHex);
Here's the modified code which runs fine for me -
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <ctype.h>
#include <string.h>
int main()
{
char hex[9] = "cf0a441f";
unsigned int hexCounter;
char *currentHex;
for(hexCounter=0; hexCounter<strlen(hex); hexCounter++)
{
currentHex = &hex[hexCounter];
printf("%c",*currentHex);
}
return 0;
}

c standard library sort function from programming pearls

#include <algorithm>
#include <stdio.h>
#include <iostream>
int intcomp(int *x,int *y) { return *x-*y;};
int a[10000];
int main(void){
int i; int n=0;
while (scanf("%d",&a[n])!=EOF)
n++;
qsort(a,n,sizeof(int),intcomp);
for (int i=0;i<n;i++)
printf("%d\n",a[i]);
return 0;
}
it is just copy of code i have two question it show me that intcomp is incompatible in this code
and also what does intcomp function?
and also what is in windows 7 EOF? how tell program that it reached EOF?
the qsort() function requires a pointer with a particular signature.
Your function has the wrong signature so it is complaining.
Your function has the signature:
int intcomp(int *x,int *y)
While qsort requires the signature:
int intcomp(void const* xp,void const* yp)
Please note the difference in the parameter types.
A corrected version of the function is:
int intcomp(void const* xp,void const* yp)
{
// Modified for C as the tag on the question changed:
// int x = *static_cast<int const*>(xp);
// int y = *static_cast<int const*>(yp);
int x = *((int const*)(xp));
int y = *((int const*)(yp));
return x-y;
}
The function qsort() is passed a function pointer as the third parameter.
This function pointer (in your case intcomp()) is used to compare values in the array passed. Each call provides pointers into the array. The result of the function should be:
Less than 0: if x is smaller than y
0: If x is equal to y
Greater than 0: If x is larger than y
First of all: the question is labeled C++ and you #include <algorithm> and <iostream>, but your code is 100% C.
Martin York already gave the answer how to correct the signature of the function you pass to qsort().
However, the "true"(TM) C++ solution would be to use std::sort<> instead of qsort!
#include <algorithm>
#include <stdio.h>
bool intcomp(int a, int b) { return a<b; }
int a[10000];
int main(void){
int n=0;
while (scanf("%d",&a[n])!=EOF)
n++;
std::sort(&a[0], &a[n], intcomp);
for (int i=0;i<n;i++)
printf("%d\n",a[i]);
return 0;
}
Note that incomp() takes ints and not int pointers, and returns a bool. Just like operator<() would.
Also note that in this case, you could forget the intcomp and just use std::sort(&a[0], &a[n]), which will use std::less<>, which will use operator<(int, int).
intcomp is an "Int Compare" function. It is passed a pointer to 2 ints and returns 0 if they are the same, a positive value is x > y and a negative value is x < y.
qsort is passed a pointer to this function and calls it each time it wants to know how to sort a pair of values.
The docs for qsort should give you some more details.
eg http://www.cppreference.com/wiki/c/other/qsort
qsort is in stdlib.h, so include that file at the beginning. Note that algorithm and iostream aren't needed.
#include <stdlib.h>
As Martin York mentioned, qsort needs a function which it will use to compare the values:
void qsort( void *buf, size_t num, size_t size, int (*compare)(const void*, const void *) );
Here is a good example on how to use qsort: http://www.cppreference.com/wiki/c/other/qsort
Edit: Ri was faster....

Resources