I tried to the identifier function try_to_change_it() with two styles as below, it produced the same result. Which style is recommend?
#include "stdafx.h"
#include <stdio.h>
// style1 declare try_to_change_it() here
void try_to_change_it(int);
int _tmain(int argc, _TCHAR* argv[])
{
int a = 1;
// style2 declare try_to_change_it() here
void try_to_change_it(int);
printf("%d\n", a);
try_to_change_it(a);
printf("%d\n", a);
return 0;
}
void try_to_change_it(int a)
{
a = 777;
}
It makes no real difference. In a typical case, you declare functions by including a header, which you normally want to do outside any function.
Related
How can I do global constant initialization like this? Is it possible at all? Or there is another way to do what I want? I mean I need global parameters gained from main() and they must be constants.
#include <stdio.h>
#include <stdlib.h>
const int var;
int main(int argc, char *argv[]) {
var = atoi(argv[1]);
/* ... */
return 0;
}
I need global parameters gained from main() and they must be constants.
No portable way to do directly as OP wants.
Code needs different access for reading and writing. Effectively hiding the access to the true data.
A close solution it to set and get data via functions defined in another file. Then no way to change data once set and only settable once.
main_var.h
int main_var_get(void);
void main_var_set(int v);
main_var.c
#include <stdlib.h>
#include "main_var.h"
static int var; // This could instead be a struct of many members.
// Or a pointer to a struct with many members.
static int var_init;
int main_var_get(void) {
if (!var_init) {
// Handle call of get before set, perhaps exit or return default value
exit(EXIT_FAILURE);
}
return var;
}
void main_var_set(int v) {
if (var_init) {
// Handle 2nd set, perhaps exit or ignore
exit(EXIT_FAILURE);
}
var = v;
var_init = 1;
}
main.c
#include <stdio.h>
#include "main_var.h"
int main(void) {
main_var_set(42);
...
printf("%d\n", main_var_get());
}
Another is to use a const int *. Access before setting is the same no-no as dereferencing NULL. Attempting to write *main_var_addr is UB like writing any const object.
main_var.h
extern const int *main_var_addr;
void main_var_set(int v);
main_var.c
#include <stdlib.h>
#include "main_var.h"
const int *main_var_addr = NULL;
static int var;
void main_var_set(int v) {
if (main_var_addr) {
// Handle 2nd set attempt, perhaps exit or ignore
exit(EXIT_FAILURE);
}
var = v;
main_var_addr = &var
}
main.c
#include <stdio.h>
#include "main_var.h"
int main(void) {
main_var_set(42);
...
printf("%d\n", *main_var_addr);
}
I don't think C allows you to initialize a constant variable elsewhere. However, you can just change var from const to static.
This is not possible, actually const doesn't mean the variable is constant in C, it's only mean that you are not allowed to change the value of the variable, but someone else could.
Global value are initialize before the main run, that mean you can't initialize at runtime, how this initialization is done is implementation behavior so there is no "pure C" way to do what you ask.
However, I don't see why you could not encapsulate your global:
my_var.h:
int init_my_var(int argc, char **argv);
int get_my_var(void);
my_var.c
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
static int var;
int init_my_var(int argc, char **argv) {
#ifndef NDEBUG
#include <stdbool.h>
#include <assert.h>
{
static bool first = true;
assert(first);
first = false;
}
#endif
if (argc < 2) {
return 1;
}
errno = 0;
long ret = strtol(argv[1], NULL, 10);
if (errno || (ret < INT_MIN || ret > INT_MAX)) {
return 2;
}
var = (int)ret;
return 0;
}
int get_my_var(void) {
return var;
}
main.c:
#include <stdio.h>
int main(void) {
printf("%d\n", get_my_var());
if (init_my_var(2, (char *[]){"", "42"})) {
return EXIT_FAILURE;
}
printf("%d\n", get_my_var());
if (init_my_var(2, (char *[]){"", "0"})) {
return EXIT_FAILURE;
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char **argv) {
int one = atoi(argv[1]);
int two = atoi(argv[2]);
int finally;
finally = func(one,two);
printf("%d",finally);
return 0;
}
int func(int first,int second) {
int counter = 0;
int new = first;
while (counter != second)
new = new*first;
counter += 1;
return new;
}
Im very new to coding so a lot of this might look like nonsense,
So this code is a complicated way of using the power arithmetic operation,5*3 == 125,
so if i type (./a.out 5 3) it should give out 125,
i seem to get this error
extension.c:15:19: warning: implicit declaration of function 'func' is invalid
in C99 [-Wimplicit-function-declaration]
finally = func(one,two);
^
1 warning generated.
Move the function declaration before the main() function / or alternatively leave it where it is and simply add a function prototype before the main().
I'm trying to populate a global int variable by passing command line arguments to a function. When I do this, I get warnings (see below), as well as a funky return number (such as 52 instead of the expected 49).
Any hints would be greatly appreciated. This is HW - but only a very small portion of the overall assignment.
#include <stdio.h>
#include <stdlib.h>
#include "kangarooHeaders.h"
int numJoeys = MIN_NUM_LEGAL_JOEYS - 1;
int main (int argc, char* argv[])
{
initializeNumJoeys(argc,argv);
printf("%d", numJoeys);
}
void initializeNumJoeys(void argc, void *argv[])
{
char line[LINE_LEN];
if (argc > MAMAS_NUM_JOEYS_CMD_LINE_INDEX)
numJoeys = *argv[1];
}
argv_test.c:13: warning: conflicting types for ‘initializeNumJoeys’
argv_test.c:9: warning: previous implicit declaration of ‘initializeNumJoeys’ was here
Put this above the main() function
void initializeNumJoeys(int argc, char *argv[]);
the reason is implicit function declaration, the compiler doesn't find a prototype for initializeNumJoeys() and implicitly declares it as
int initializeNumJoeys();
so when it finds the definition, then it's conflicting with the previous declaration.
Also, change this
numJoeys = *argv[1];
to
numJoeys = strtol(argv[1], NULL, 10);
and also, the function signature is wrong
void initializeNumJoeys(void argc, void *argv[])
/* ^ should be int */
so change it to
void initializeNumJoeys(int argc, void *argv[])
don't forget to fix the prototype.
#include <stdio.h>
#define MAX 9
void main (int argc, char *argv[]) {
printBoard();
}
void printBoard(void) {
int row,col;
row=col=0;
for(row;row<MAX;row++) //row navigation
for(col;col<MAX;col++){//column navigation
printf("r:%d,c:%d",row,col);
}/*End Column Nav*/
printf("\n");
}
I'm not sure what I am doing wrong here - the error I get :
"warning: conflicting types for ‘printBoard’ [enabled by default]
note: previous implicit declaration of ‘printBoard’ was here"
Try adding a function prototype for printBoard above main() e.g.,
void printBoard(void);
void main(...)
You have declared function after calling it.
#include <stdio.h>
#define MAX 9
void printBoard(void) {
int row,col;
row=col=0;
for(row;row<MAX;row++) //row navigation
for(col;col<MAX;col++){//column navigation
printf("r:%d,c:%d",row,col);
}/*End Column Nav*/
printf("\n");
}
void main (int argc, char *argv[]) {
printBoard();
}
This should work pretty fine.
Edit: You should declar all function before calling any of them.
Like void printBoard(void);
You are calling the method before it is declared.
Solve the problem by:
1) Moving the definition of void printBoard(void) above main or
2) adding a declaration above main. Just this line: void printBoard(void);
I need several global pointers to be shared among a few files - the pointers are essentially arrays of double whose lengths are only determined at runtime.
I include here the pieces of the code that caused the issue. This is not the exact code, but it illustrates all the points precisely:
foo.h
#ifndef FOOH
#define FOOH
/* ------------------
COMMON VARIABLES
---------------------*/
// create_bundles.c
extern double *all_bundle;
/* ------------------
COMMON FUNCTIONS
---------------------*/
// create_bundles.c
void create_bundles(int num_firm);
// memory_allocation.c
void allocate_memory(int num_firm, int num_bundle);
void clean_memory(void);
#endif
create_bundles.c
#include "foo.h"
extern double *all_bundle;
void create_bundles(int num_firm) {
int i;
for (i = 0; i < num_firm; i++) {
all_bundle[i] = 1
}
memory_allocation.c
#include "foo.h"
// create_bundles.c
double *all_bundle = NULL;
void allocate_memory(int num_firm, int num_bundle) {
all_bundle = calloc(num_bundle * num_firm, sizeof(double));
}
void clean_memory(void) {
free(all_bundle);
}
main.c
#include "foo.h"
void main(int num_firm, int num_bundle) {
allocate_memory(num_firm, num_bundle);
create_bundles(num_firm);
clean_memory();
}
What happened is that if I print out all_bundle[i] it'll all be 0, and then it'll give me a segmentation error.
Why the error and how to fix it?
The problem is not in global pointer, but something else. Keep looking for the problem in your common code. I hope you are trying to print contents of all_bundle array before calling clean_memory. I have edited your code a little bit and it works great without any segmentation errors and prints 1.0000. Here it is, take a look:
foo.h:
#ifndef FOOH
#define FOOH
// create_bundles.c
extern double *all_bundle;
// create_bundles.c
void create_bundles(int num_firm);
// memory_allocation.c
void allocate_memory(int num_firm, int num_bundle);
void clean_memory(void);
#endif
memory_allocation.c:
#include <stdlib.h>
#include "foo.h"
double *all_bundle = 0;
void allocate_memory(int num_firm, int num_bundle) {
all_bundle = calloc(num_bundle * num_firm, sizeof(double));
}
void clean_memory(void) {
free(all_bundle);
}
create_bundles.c:
#include "foo.h"
void create_bundles(int num_firm) {
int i;
for (i = 0; i < num_firm; i++) {
all_bundle[i] = 1;
}
}
main.c:
#include <stdio.h>
#include "foo.h"
int main(int argc, char *argv[]) {
allocate_memory(100, 1);
create_bundles(100);
{
int i;
for(i = 0; i < 100; ++i)
printf("%f\n", all_bundle[i]);
}
clean_memory();
return 0;
}
Have a header file to access the memory (i.e. add stuff to it, remove stuff from it, readf bits of it, etc).
Have the corresponding .c (or .cpp if that fancies you) to do the magic. And then use static to define the memory.
This is a simple and easy solution to your problem and also enables you to change the implementation if it is required to do so.