Changing undefined values of an array - c

lets think of a two dimensional array; which looks like this:
[1][2][3][4][undefined][undefined][undefined]
[5][6][7][8][undefined][undefined][undefined]
[9][0][1][2][undefined][undefined][undefined]
Can I change the undefined values with a for loop like this?
for (i=0;i<7;i++)
{ for (j=0;j<3;j++)
{
if (Arr[i][j]=="the value of undefined, which I wonder")
Arr[i][j]=0;
}
}
I remember using NULL keyword on C#, but that obviously doesnt work for C.
Thank you for your help!
Note: I dont need any other methods than that to solve the problem, just wondering if there is a keyword or phrase to help me solve it that way.

If the elements of the array are a floating-point type, you can use a NaN to indicate that they are not set to a number (in most C implementations; this is not in all C implementations but is common). You would have to initialize the array to contain NaNs; they will (generally) not be placed there by default.
If the elements of the array have another type, you would have to select a value to designate that the element has not been otherwise assigned yet, and that could create problems using the array normally.
After you #include <math.h>, you can test whether a C implementation supports NaNs with:
#if defined NAN
// NaNs are supported.
#else
#error "This program requires support for NaNs."
#endif
You can test whether an object x is a NaN with:
if (isnan(x)) …
You can set an object to a NaN with:
x = NAN;

In addition to Eric's answer, there are several other ways to handle this sort of situation in C, with varying amounts of extra baggage and mental grief. That is: these are ways to to express a value which represents undefined or unset values in your domain. We are not talking about the actual indeterminate values you will generally get back from your C implementation if you allocate an array without initializing it and then access it.
Method 1: NaN (not-a-number) values, as indicated in Eric's solution. Works in the specific case where you are manipulating floats, and there is no possibility that NaN is going to be used as a legitimate defined value in your domain. If you were storing characters, the null character '\0' might also be a reasonable choice for undefined.
Method 2: Pointers. C does have NULL, just like C#. However, it only applies if you're manipulating values of pointer types. So, instead of:
int a[3];
a[0] = 1;
a[1] = 2;
a[2] = 0; /* blech -- I really want this to mean 'undefined',
but what if I really needed 0 as a numeric value
in my array? In that case, this doesn't work! */
I could do this:
#include <stdlib.h>
int* integer_new(int i) {
int* result = (int*) malloc(sizeof(int));
*result = i;
return result;
}
int* a[3];
a[0] = integer_new(1);
a[1] = integer_new(2);
a[2] = NULL;
and now you have a value which can easily be tested and distinguished from your normal integer values. This is in theory what's going on behind the scenes in the C# code, I believe. But you can see the disadvantages pretty quickly: you have a bunch of heap-allocated objects now where you didn't before, and you now have to manage them, freeing them as appropriate when you're done with them.
There's a refinement of this if you're dealing with something like the flyweight pattern where these values are stack-allocated or pre-allocated elsewhere. In that case, you could just take the addresses of those values, stick them in the array, and not have to heap-allocate them yourself. But you still have to contend with an extra layer of indirection.
Method 3: The maybe pattern (which I'm stealing from Haskell). Something like this:
typedef struct maybe_int_ {
int has_value; /* 1 if yes, 0 if no */
int value;
} maybe_int;
maybe_int maybe_nothing(void) {
maybe_int result;
result.has_value = 0;
return result;
}
maybe_int maybe_just(int i) {
maybe_int result;
result.has_value = 1;
result.value = i;
return result;
}
maybe_int a[3];
a[0] = maybe_just(1);
a[1] = maybe_just(2);
a[2] = maybe_nothing();
This works better with the stack, so it's generally an improvement over pointers in that way, but you still have a lot more to deal with for bookkeeping.
Method 4: Unions. Similar to Method 3, but you might do something like this if you can have multiple kinds of values in your array:
typedef enum {
BOXED_TYPE_UNDEFINED,
BOXED_TYPE_INT,
BOXED_TYPE_FLOAT
} boxed_type;
typedef struct boxed_ {
boxed_type type;
union {
int int_value;
float float_value;
} u;
} boxed;
boxed boxed_undefined(void) {
boxed result;
result.type = BOXED_TYPE_UNDEFINED;
return result;
}
boxed boxed_int(int i) {
boxed result;
result.type = BOXED_TYPE_INT;
result.u.int_value = i;
return result;
}
boxed boxed_float(float f) {
boxed result;
result.type = BOXED_TYPE_FLOAT;
result.u.float_value = f;
return result;
}
boxed a[3];
a[0] = boxed_int(1);
a[1] = boxed_float(2.0f);
a[2] = boxed_undefined();
If you're already using a union plus a type discriminator, then this solution might be particularly easy to implement.
What do all these solutions have in common? The idea of a sentinel value: some value you're storing in your array which is guaranteed to not be used for anything else in your domain, so you're free to interpret it to mean an undefined value. As you can see, there are a lot of ways to inject sentinel values into your domain.
Here's one solution that doesn't involve sentinel values. Method 5: go outside the box.
int a[3];
unsigned char adef[3];
a[0] = 1; adef[0] = 1;
a[1] = 2; adef[1] = 1;
adef[2] = 0; /* I would set a[2] = 0 here as well
because I dislike uninitialized
array values! */
If you really can't muck with the values in your domain in any way that would allow you to define a sentinel value, then just store the extra "definedness" of values somewhere else. I've never had to resort to this myself, but I have found that the general technique of a separate table of related data does come in handy from time to time.

Let me say , there is no value means:"the value of undefined, which I wonder" , if you didn't initialized it , it is unkown value.

Arrays in C have undefined value if you do not initialize them to a value; That means it can be 0 0 0 0 0 900000 0 0 0 0 0 etc.
Yes there is a undefined value but as per the name it's well ...undefined - as in there is no set value.
You can just overwrite them like you are doing. . Even better though would be to use memset
The reason it's undefined is you're just getting a chunk of memory - anything could be sitting (value wise) in that memory.
edit: ok unless you static init the array of course.

Related

if statements in c with NULL

I have a program that looks something like this:
int someVal = 5;
int startCol = NULL;
int startRow = NULL;
int destCol = NULL;
int destRow = NULL;
for (int i = 0;i<2;i++){
if (startCol == NULL){
startCol = someVal;
}
// same for other variables
}
so basically i want to change the value of the variables at the first time it is being checked but not after.
how can i do that? in python i would use None but it appears i can't use NULL with int. I can't just set the values to 0 because i use them after for array indexes so if the value is 0 i will access the first value but i don't want to.
NULL when assigned to the integer converts to zero.
int variables do not have any special value which means "not initialized" or "no value".
The only workaround is to choose one integer value which will indicate that variable needs initialization. You can also define more complex data types holding the information about needed initialization
typedef struct
{
bool initialized;
int val;
}myInt_t;
myInt_t x = {.initialized = false};
if (!x.initilaized) x.val = 100;
But the best way is to have correct program algorithm and to program carefully, remembering about not initialized variables.
If you are using them for indices, setting them to -1 isn't a bad idea.
Then you will have only to check if they are -1.
NULL is ((void*)0). It is a pointer. Mixing int and pointer isn't really the best practice but produces the desired output if it is used well.
If you are using the code from the snippet, isn't it an option to just check if i == 0?
NULL is for pointers.
ints are just int values and not references. You can assign them to NULL and test if they are NULL but NULL is just a number (if used as int (I think it is 0).
If you use it as a pointer, it will point to an address that is not available (dereferenceing it will cause a SEGENV) and you can use it in order to not assign any data with it.

Remapping C pointer to a 3D array

I am trying to get a pointer to an array integers to be temporarily remapped in a function later on to save myself pointer math. I've tried to see if any other questions answered it, but I've been unable to reproduce the methods described here, here, and here.
Fundamentally, I just want to temporally treat an integer group and a 3D array to be sure that I don't mess up the pointer math. (I'm looking at this currently because the previous code had made inconsistent assignments to the memory).
#include <stdlib.h>
#define GROUPCOUNT 16
#define SENSORCOUNT 6
#define SENSORDIM 3
int main()
{
int *groupdata = (int *)calloc(GROUPCOUNT * SENSORCOUNT * SENSORDIM,sizeof(int));
int sensordata[SENSORCOUNT*SENSORDIM];
sensordata[7] = 42; //assign some data
int (*group3d)[GROUPCOUNT][SENSORCOUNT][SENSORDIM] = groupdata; //<---Here is the problem
group3d[1][5][1] = sensordata[7]; //I want to do this
free(groupdata);
}
In the example above, I want to handle groupdata as group3d temporarily for assignments, and I just cannot seem to wrap myself around the casting. I currently have macros that do the pointer math to enforce the correct structure, but if it was all just in the code, it would be even better when I pass it off. Any suggestions would be greatly appreciated.
note: The 3D cast is to be used in a function way in the bowels of the program. The example is just a minimally viable program for me to try to sort out the code.
When group3d is defined with int (*group3d)[GROUPCOUNT][SENSORCOUNT][SENSORDIM], then *group3d is a three-dimensional array. That would let you use it with (*group3d)[1][5][1].
To use it with group3d[1][5][1], you need group3d to be a pointer to a two-dimensional array:
int (*group3d)[SENSORCOUNT][SENSORDIM] = (int (*)[SENSORCOUNT][SENSORDIM]) groupdata;
(There are some technical concerns about C semantics in aliasing an array of int as an array of array of array of int, but this is not a problem in common compilers with default settings. However, it would be preferable to always use the memory as an array of array of array of int, not as an array of int.)
int l = 5, w = 10, h = 15;
int Data = 45;
int *k = malloc(l * w * h * sizeof *k);
// not use this k[a][b][c] = Data;
//use this is right
k[a*l*w + b*l + c] = Data;
In the example above, I want to handle groupdata as group3d
temporarily for assignments, and I just cannot seem to wrap myself
around the casting.
One possible solution is to create a multidimensional array dynamically like this. This way you won't have to cast things or worry about the dimensions.
int (*group3d)[GROUPCOUNT][SENSORCOUNT][SENSORDIM] = calloc(1, sizeof(int [GROUPCOUNT][SENSORCOUNT][SENSORDIM]));
(*group3d)[1][5][1] = sensordata[7]; //I want to do this
/* Then you can print it like */
printf("%d\r\n", (*group3d)[1][5][1]);

Can I write a function that can either return one data type or another in C?

How can I make a function that either returns zero or an array of numbers. My function should test if the input string with a string two hexadecimal numbers separated by a space, such as this string: "a48 2b4". If it does qualify, return an int array of the two numbers, if not, like if it has non hex characters or too many spaces, return 0. How can I do this in c?
I could also use a Union. A union can store two or more types of values.
union OptionalInt {
int Value;
bool IsNull;
};
union OptionalInt ParseHex(char *Str) {
//...
if(/*Success*/) {
return (union OptionalInt){/*Value*/, 0};
}else{
return (union OptionalInt){0, 1};
}
}
Since you cannot directly return an array in any case, you're going to need to modify your plan. Consider first that the two alternative returns you describe are largely unrelated -- one is data, the other a status code. They do not fit well as alternatives, and that's one of the reasons you are struggling.
A nice, clean design would follow from the alternative #try-catch-finally suggested in comments: let the caller pass (a pointer to) an array to the function as an argument. On success, the function fills in the first two elements (relying on the caller to have provided a pointer suitable for that). The function's actual return value can then be a status code. I guess the way you're thinking about it, that would be 0 on failure and something else (1?) on success, though that's backwards from the way most standard library functions do it.
Example:
int parseHex(const char *str, int *parsed_result) {
// ...
if (success) {
parsed_result[0] = hex0;
parsed_result[1] = hex1;
return 1;
} else {
return 0;
}
}
There are at least two other ways you could approach the problem, but this one is clean and consistent, and does not saddle the caller with any new responsibility for freeing dynamically-allocated memory.

How to change a variable whose name is the user input?

For example, I have this block:
int nFirst, nSecond;
char sInput[10];
printf("Which variable to change to 10?");
scanf("%s", &sInput);
// BAD - inflexible and unmaintainable
if(strcmp(sInput,"nFirst") ==0){
nFirst = 10;
}
else if (strcmp(sInput,"nSecond")==0) {
nSecond =10;
}
Is there a nice way to do this? like treat a string as if its a variable name?
No, there is no "nice" way of doing this in C. Variable names (typically) aren't preserved in the generated machine code, except to support debugging. C doesn't have a built-in mechanism for translating a string value into a reference to a variable of the same name.
You would have to map variable names to variables manually. You could build a lookup table, associating a string value with the address of the corresponding variable:
struct vn {
char *varname;
void *addr;
Typeinfo t;
};
where Typeinfo is some enumeration or other mechanism for encoding the type of the variable, giving you something to the effect of
int foo;
double bar;
char *blurga;
struct vn varsByName[] = { {"foo", &foo, IntType},
{"bar", &bar, DoubleType},
{"blurga", blurga, CharPtrType} };
I don't recommend doing this.
Another, platform-dependent approach is to put all your variables into a shared library and then have access to them by names. Have a look at dlsym/dlopen functions.
void* handle = dlopen("mysymbols.so", RTLD_LOCAL | RTLD_LAZY);
int* var = (int*) dlsym(handle, user_typed_name);
*var = 10; /* modify the variable */
You could implement something like a dictionary or a two-dimensional array which contains the "variable name" and the value. Then this comes down to setting an array element to a new value.
Other than that: C# and other object oriented languages would allow this through reflection, but as C itself isn't object oriented, you can not do that (C++ support for this seems to be very limited).
You can do it with a macro:
#define MAYBESET(name) if (strcmp(sInput, #name) ==0 ){ name = 10; }
#name is the real value of name changed to a string literal.
For a small number of variables then your algorithm should perform well. If there are many variables that could be changed, rather than just two, then another algorithm should be considered. Making this pretty and clear isn't exactly easy in C.
If you really wanted this to be faster you could either do a hash table or use a switch/case like:
int First, Second; // Note that I got rid of your leading n
char sInput[10];
printf("Which variable to change to 10?");
scanf("%s", &sInput);
// BAD - inflexible and unmaintainable
// referring to character array overflow potential, I assume
switch (sInput[0])
{
case 'F':
if (0 == strcmp("irst", sInput+1) )
{
First = 10;
} else
{
// error
}
break;
case 'S':
if (0 == strcmp("econd", sInput+1) )
{
Second = 10;
} else
{
// error
}
break;
default:
// error
break;
}
If you don't like the way that this looks then you could use macros (#define) to make it less big looking, but it would turn out the same. Another option that you could employ would be to write a small program that output the source code of this program which would handle all of the repetitive and tedious parts.
Another way to do this, if all of the variables are of the same type, would be to create an array of them and input their index in rather than a name, but then you have to add code to check against inputting an index out of range of the size of the array.

Are basic data types in C mutable or immutable by default?

I've found many information about the mutability of data types in C#,java... But what about pure C.
for example, is int immutable in C by default?
For example, looking at the following code example:
#include <stdio.h>
int main()
{
int a,b,c;
b=0;
c=0;
a=b+c;
b=1;
c=2;
printf("1st time %d\n",a);//gives out 0
c=3;
printf("2nd time %d",a);//gives out 0
return 0;
}
The above code shows that an ordinary int is immutable, am I right?
[I]s int mutable in C?
The short answer: yes it is!
If you are asking whether it is possible to mutate any memory location in C, the answer is yes. (Sometimes with dangerous consequences!) While it is possible to design a data structure that cannot be mutated directly through the API you have created for it, you can pretty much overwrite any memory location in pure C.
No wonder some love it, others don't.
EDIT
In reference to Roger's remark above:
#include<stdio.h>
int main (int argc, char *argv[]) {
const int n = 1;
int *m = &n;
*m = 10;
printf ("%d\n", n); /* prints 10 */
return 0;
}
So, yes, it is possible to overwrite the memory location of even const ints.
Ordinary int is mutable. An entity that is (not merely claimed to be at some point, but "really is") const is not-mutable-in-theory and if the hardware and software cooperate, often not-mutable-in-fact as well.
Defining a variable using the const qualifier makes it "really" const:
const int c3 = 3;
void f(void) {
const int c4 = 4;
...
}
With "tricky" code (casting away the const-ness) you can convince the system to write, or attempt to write, new values into c3 and/or c4:
void f(void) {
const int c4 = 4;
int *p;
p = (int *)&c3;
*p = 99;
printf("c3 is now %d\n", c3);
}
If you call f() you may, on some systems, find that c3 changes and becomes 99. On other systems you may get a "segmentation fault" or other run-time error.
Change the references to use c4 and the same things can happen—although in practice, few if any systems produce a run-time error. However, you may observe something else entirely: instead of printing c4 is now 99 you may get c4 is now 4.
This last can happen because the compiler is allowed to assume that, having made c4 a const int with value 4, you, the programmer, never changed it. That *p = 99 must not have changed it (even if it did), so the call to printf can be replaced with a different call that just prints 4.
The same is generally true of references to c3: the compiler can assume that since you promised never to change it, you never actually did change it. This can produce surprising results, such as: p == &c3 being true, c3 being 3, and *p being 99. But a run-time error is pretty likely, because most modern compilers and OSes cooperate to stick c3 into a read-only region.
When string literals produce arrays (which is most of the time), C has a quirk. These arrays are not const-qualified, but the characters making up the array are read-only anyway (at least in principle, as with const int c3 = 3;). Like c3, most modern systems manage to make them "really read-only".
(String literals do not produce arrays when they are used as initializers for objects of type array of char. Compare:
char *ronly = "this string is read only";
char rwarray[] = "this string is read/write";
Here ronly is a pointer, not an array, so the string literal produces an array and ronly points to the first character of that array. The underlying array is read-only, even though its type is char [25]. But rwarray is an array, not a pointer, so the string literal fills it in—and sets its size to 26—and it is mutable. You would have to write const char roarray[] = ... to make it immutable. [Some like to spell the type char const [], with the const coming after the data-type. These mean the same thing.])
I think you are fundamentally misunderstanding what it means to be mutable or at the very least how procedural languages work. Here is your code with the values of a,b and c commented in:
#include <stdio.h>
int main(void) // Good practice to declare main with `(void)` instead of ()
{
int a,b,c; // a,b, and c are garbage values (whatever was left in memory)
b=0; // a == garbage, b == 0, c == garbage
c=0; // a == garbage, b == 0, c == 0
a=b+c; // a == 0, b == 0, c == 0
b=1; // a == 0, b == 1, c == 0
c=2; // a == 0, b == 1, c == 2
printf("1st time %d\n",a);
c=3; // a == 0, b == 0, c == 3
printf("2nd time %d",a);
return 0;
}
Once a is assigned, it isn't magically updated because c and b change. That has nothing to do with mutability vs. immutability. In fact, by assigning b and c to 0 and then later reassigning them to 1 and 2 respectively, you demonstrated that ints (and all data types in C that are not declared const actually) are in fact mutable.
While this is not an answer, I am not 'reputed' enough to comment or vote.
Lovely piece on C constness by #torek above (Also a reason for those online testers to not include such raw questions in their multiple choice questions).
As a beginner in javascript where the term 'mutable' means (I think) that you can add properties to it (using the 'prototype' object in javascript).
In any case, in the code piece you wrote in the question, the statement a=b+c; only changes the value of 'a' with the values of 'b' and 'c' at that point in the code block (which are both 0), with all 3 variables retaining their original addresses. So any changes you make to the assigning variables after the statement will not affect the value of 'a'. And in C, this fact doesn't make it 'immutable', which means the value cannot be changed.

Resources