Can you help me explaining the following C code? [duplicate] - c

This question already has answers here:
C code explanation
(2 answers)
Closed 6 years ago.
int main(int argc, char **argv)
{
int (*func)();
func = (int (*)()) code;
(int)(*func)();
}
the variable code has some shellcode in it

Function pointers. This code snippet should help you understand.
#include <stdio.h>
int Hello();
int code();
int main(int argc, char **argv)
{
int (*func)(); //pointer to function that takes no arguments quivalent to: int (*func)(void);
func =&Hello;
int x = func();
printf("%d\n", x);
func = (int (*)()) code; // Assigns the pointer from the code function to the func pointer
x = code();
printf("%d", x);
}
int code()
{
printf("code returns: ");
return 500;
}
int Hello()
{
printf("hello returns: ");
return 1;
}

code probably is a variable that correspond to the address of some machine code in memory. Then a pointer to function that takes no parameter and returns an int is set to that address and the function is called. int f() is the prototype for a function with no param and int as return value, then int (*pf)() is a pointer to such a function.

Related

Difference between int main(void) and int main() [duplicate]

This question already has answers here:
Difference between int main() and int main(void)?
(10 answers)
Closed 9 months ago.
#include <stdio.h>
int main()
{
static int i = 5;
if (--i){
printf("%d ", i);
main(10);
}
}
I was reading article on geeksforgeek the difference between int main(void) and int main() but I am confused. How main function taking arguement?
int main(void) { }
Here, you are telling your compiler explicitly that your main() function is not going to take any arguments. This prototype of main() function is standard.
int my_func(void)
{
return 100;
}
// the above function can be called as:
// 1. my_func(); --> good
// 2. my_func(21); --> error
// 3. my_func("STACKOVERFLOW"); --> error
int main() { }
Here, you are telling your compiler implicitly that your main() function is not going to take any arguments. But, there's a plot twist, in C leaving the function without any arguments (type function() { }) means you can put any value/variable in it while calling that function. This prototype should be avoided.
int my_func()
{
return 100;
}
// the above function can be called as:
// 1. my_func(); --> no error
// 2. my_func(21); --> no error
// 3. my_func("STACKOVERFLOW"); --> no error

Implementing string to int function in c [duplicate]

This question already has answers here:
returning a local variable from function in C [duplicate]
(4 answers)
Changing address contained by pointer using function
(5 answers)
Closed 1 year ago.
I am trying to implement a function as stated in the title. I think I am very close to solution but a problem.
input: 51% are admitted.
output: x:51 (null)
but output should have been:
s:% are admitted.
My try is here:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int str2int(int);
int isdigit(int);
long str2double(int);
int driver(char *, char *);
int main(){
char *s = "51% are admitted.";
char *sPtr;
int x = driver(s, sPtr);
printf("x:%d sPtr:%s", x, sPtr);
return 0;
}
int isdigit(int ch){
return (ch>=48 && ch<=57)?1:0;
}
int str2int(int ch){
return ch-48;
}
int driver(char *s, char *sPtr){
int i=0, number=0;
while(s[i]!='\0' && isdigit(s[i])){
number = number*10 + str2int(s[i]);
i++;
}
sPtr=s+i;
printf("%s\n", sPtr);
return number;
}
The problem is, in main, sPtr seems as null but in driver function, sPtr is % is admitted which is what it should be. How can I fix the problem so that I can print the solution correctly without using a printf statement in driver function?
EDIT:
The problem is as #Johnny Mopp said, I was trying to pass a copy of that variable. Therefore, I need to pass the address of variable of *sPtr which appears char **sPtr in prototype. And the code should be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int str2int(int);
int isdigit(int);
long str2double(int);
int driver(char *, char **);
int main(){
char *s = "51% are admitted.";
char **sPtr;
int x = driver(s, &sPtr);
printf("x:%d sPtr:%s", x, sPtr);
return 0;
}
int isdigit(int ch){
return (ch>=48 && ch<=57)?1:0;
}
int str2int(int ch){
return ch-48;
}
int driver(char *s, char **sPtr){
int i=0, number=0;
while(s[i]!='\0' && isdigit(s[i])){
number = number*10 + str2int(s[i]);
i++;
}
*sPtr=s+i;
return number;
}
Thanks for contributes of #Johnny Mopp and #paulsm4

What is the meaning in C when a function is in another function's name (not in the arguments)?

Why is
"void (*parse(char *op))(int, int)"
written like this? (main added to give use case), it gets called from a pointer "fun" with argv[2] without the ints (line 18)... and then again as "fun" with the ints (line 21)?
void (*parse(char *op))(int, int)
{
if (!strcmp(op, "+"))
return(other stuff...);
else
return (0);
}
int main(int argc, char *argv[]){
int a;
int b;
void (*fun)(int, int);
if (argc == 4){
a = atoi(argv[1]);
fun = parse(argv[2]);
b = atoi(argv[3]);
if (fun)
fun(a, b);
else
return(0);
}
return(0);
}
How does it technically work, and it is just a showoff with a simpler way to write it or is this the only correct grammar?
parse() is a function that returns a function pointer. You can use typedef with the type of the returned function to make it look a lot nicer, though:
#include <string.h>
#include <stdlib.h>
// parser_func describes a function that takes two ints and returns nothing
typedef void (*parser_func)(int, int);
// Like this one.
void somefunc(int a, int b) {}
// And parse() is a function that takes a char* and returns a
// pointer to a function that matches parser_func.
parser_func parse(char *op) {
if (!strcmp(op, "+"))
return somefunc;
else
return NULL;
}
int main(int argc, char *argv[]) {
int a;
int b;
parser_func fun; // Function pointer
if (argc == 4) {
a = atoi(argv[1]);
fun = parse(argv[2]); // Assign a function to fun
b = atoi(argv[3]);
if (fun) {
fun(a, b); // And call it if it's not null
}
}
return 0;
}
Why is void (*parse(char *op))(int, int) written like this?
Because that is the syntax for returning a pointer to function. The return type is void (*)(int, int) which is a pointer to function that returns void and accepts two int arguments.
Usually, type aliases are used to make pointers to functions more readable:
typedef void operation(int, int);
using operation = void (int, int); // equivalent C++ alternative
operation* parse(char *op);

function pointer that takes and returns a pointer [duplicate]

This question already has answers here:
C function pointer syntax
(4 answers)
Closed 4 years ago.
I'm trying to get this code to run..
#include <stdio.h>
int *myMethod(int *a)
{
printf("Hello");
return a;
}
int main()
{
// my_ptr is a pointer to function myMethod()
int *my_ptr(int *) = myMethod;
// Invoking myMethod() using my_ptr
int a = 5;
int *p = (*my_ptr)(&a);
printf("Bye %d\n", *p);
return 0;
}
I thought my syntax for a function pointer, my_ptr, would be correct where it could take an int pointer as it's parameter and return an int pointer but when I compile it, I get the error that:
error: function 'my_ptr' is initialized like a variable
int *my_ptr(int *) = myMethod;
Could someone explain the error/issue? Thanks!
int* my_ptr(int*) is the prototype of a function. You want a function pointer: int* (*my_ptr)(int*)
Change pointer to function myMethod to this:
int *(*my_ptr)(int *) = &myMethod;
You should use int *(*my_ptr)(int *) = myMethod; not int *my_ptr(int *) = myMethod;
The following code could work:
#include <stdio.h>
int *myMethod(int *a)
{
printf("Hello");
return a;
}
int main()
{
int *(*my_ptr)(int *) = myMethod;
int a = 5;
int *p = (*my_ptr)(&a);
printf("Bye %d\n", *p);
return 0;
}

Reference to a pointer is lost [duplicate]

This question already has answers here:
Assignment of function parameter has no effect outside the function
(2 answers)
Closed 9 years ago.
I am trying to understand why this statement doesn't work.
char resp[] = "123456789";
void getValue(char *im)
{
im = resp;
printf("\n%s\n",im);
}
int main(int argc, char *argv[])
{
char imei[11] = {0};
getValue(imei);
printf("\nIMEI: %s\n",imei);
return 0;
}
Output:
123456789
IMEI:
You can not assign with =, use strcpy instead:
#include <stdio.h>
#include <string.h>
char resp[] = "123456789";
void getValue(char *im)
{
im = strcpy(im, resp);
printf("\n%s\n",im);
}
int main(int argc, char *argv[])
{
char imei[11] = {0};
getValue(imei);
printf("\nIMEI: %s\n",imei);
return 0;
}
That's because imei is an array[11] (not just a pointer to), if you want to assign via = you can:
#include <stdio.h>
char resp[] = "123456789";
void getValue(char **im)
{
*im = resp;
printf("\n%s\n",*im);
}
int main(int argc, char *argv[])
{
char *imei; /* Not an array but a pointer */
getValue(&imei);
printf("\nIMEI: %s\n",imei);
return 0;
}
C passes parameters by value. Whatever change you ale to the im will be lost when the function exits. If you want to preserve the change. Pass the address of the pointer. Then you can change the pointer at the address you pass.
Try this:
char resp[] = "123456789";
void getValue(char **im)
{
*im = resp;
printf("\n%s\n",*im);
}
You need to pass a pointer to a pointer as your program argument.

Resources