I'm given a method header as so:
char* thisMethod(char* input){}
is it possible to say,
char var = input[0];
? I know that "input" will be in the form of a char array.
I'm obviously new to C++ pointers are throwing me off. I tried researching how to work with char pointer function arguments but couldn't find anything specific enough to help. Thanks for the help.
There is a misconception that may lead you into further troubles:
I know that "input" will be in the form of a char array.
NOPE: By the scope of that function, input is a pointer to a character. The function has no way to know where such a pointer comes from.
If it has been taken from an array upon calling the function than it will be a pointer to the first element of that array.
Because pointer have an arithmetic that allows to add offsets and because the [] operator applied to pointers translates as a[b] = *(a+b) by definition, in whatever code, if a is a pointer, *a and a[0] are perfect synonymous.
Think to an array as a sequence of boxes and a pointer as your hand's index finger
adding an offset to a finger (like finger+2) means "re-point it aside" and de-referencing it (like *finger) means "look inside what it points to".
The [] operator on pointers is just a shortcut to do both operations at once.
Arrays are another distinct thing. Don't think to them when dealing with pointers, since -in more complex situations, like multidimensional array or multi-indirection pointers - the expression a[b][c] won't work anymore the same way.
There are two ways to get a value from a pointer, * and []. The following are equivalent:
char var1 = *input;
char var2 = input[0];
Using the brackets is more common when you know you were passed an array, since it allows you to supply an index. You need some way of knowing where the end of the array is so that you don't attempt any access past it, your function is missing that important detail.
As long as it's inside the function and input points to something valid ( not NULL/nullptr and not a garbage location ) then doing char var = input[0]; is just fine. It's the same as char var = *input.
P.S If it's supposed to be a string I recommend using std::string.
Related
I want to know whether a pointer is pointing to an array or single integer. I have a function which takes two pointer (int and char) as input and tell whether a pointer is pointing to an array or single integer.
pointer=pointer+4;
pointer1=pointer1+4;
Is this a good idea?
Like others have said here, C doesn't know what a pointer is pointing to. However if you should choose to go down this path, you could put a sentinel value in the integer or first position in the array to indicate what it is...
#define ARRAY_SENTINEL -1
int x = 0;
int x_array[3] = {ARRAY_SENTINEL, 7, 11};
pointer = &x_array[0];
if (*pointer == ARRAY_SENTINEL)
{
// do some crazy stuff
}
pointer = &x;
if (*pointer != ARRAY_SENTINEL)
{
// do some more crazy stuff
}
That's not a good idea. Using just raw pointers there's no way to know if they point to an array or a single value.
A pointer that is being used as an array and a pointer to a single values are identical - they're both just a memory address - so theres no information to use to distinguish between them. If you post what you want to ultimately do there might be a solution that doesn't rely on comparing pointers to arrays and single values.
Actually pointers point to a piece of memory, not integers or arrays. It is not possible to distinguish if an integer is single variable or the integer is an element of array, both will look exactly the same in memory.
Can you use some C++ data structures, std::vector for example?
For C++ questions, the answer is simple. Do not use C-style dynamic arrays in C++. Whenever you need a C-style dynamic array, you should use std::vector.
This way you would never guess what the pointer points to, because only std::vector will be holding an array.
I want to know whether a pointer is pointing to an array or single integer. I have a function which takes two pointer (int and char) as input and tell whether a pointer is pointing to an array or single integer.
pointer=pointer+4;
pointer1=pointer1+4;
Is this a good idea?
Like others have said here, C doesn't know what a pointer is pointing to. However if you should choose to go down this path, you could put a sentinel value in the integer or first position in the array to indicate what it is...
#define ARRAY_SENTINEL -1
int x = 0;
int x_array[3] = {ARRAY_SENTINEL, 7, 11};
pointer = &x_array[0];
if (*pointer == ARRAY_SENTINEL)
{
// do some crazy stuff
}
pointer = &x;
if (*pointer != ARRAY_SENTINEL)
{
// do some more crazy stuff
}
That's not a good idea. Using just raw pointers there's no way to know if they point to an array or a single value.
A pointer that is being used as an array and a pointer to a single values are identical - they're both just a memory address - so theres no information to use to distinguish between them. If you post what you want to ultimately do there might be a solution that doesn't rely on comparing pointers to arrays and single values.
Actually pointers point to a piece of memory, not integers or arrays. It is not possible to distinguish if an integer is single variable or the integer is an element of array, both will look exactly the same in memory.
Can you use some C++ data structures, std::vector for example?
For C++ questions, the answer is simple. Do not use C-style dynamic arrays in C++. Whenever you need a C-style dynamic array, you should use std::vector.
This way you would never guess what the pointer points to, because only std::vector will be holding an array.
I have a function in my c++ application that needs an integer as an input. Sadly this integer is only available in form of an usigned char array, which inclines me to do this:
unsigned char c[4] = {'1','2','3','4'};
void myFuncThatBadlyNeedsInts(int i)
//compares some memory value(which is an int) with anotherone...
myFuncThatBadlyNeedsInts((int)c);
This gives me an error, which tells me that this is not allowed.
But if i decide to get tricky and do this:
myFuncThatBadlyNeedsInts(*((int*)&c));
Now the program goes about and gives me always the result i want. My question is: Why is there a diffrence in the result of the two casts?
Shouldn't they both do the same, with the diffrence i have two unneccessary pointers in the process?
Help or the guidance to an alredy existing answer to my qustion is much appreciated.
EDIT (since i can't comment): The need for this indeed silly conversion is inheritated from a project which compares a specific memory location (as an int) with a DWORD wich is retrived from a FGPA and comes as an array. The DWORD gets read in the end as one hex-number.
I'll try to get permission to change this and THANK YOU ALL for the quick responses. I really didn't get the part of this program nor did I understand why it worked like this in the first place. Now I know someone got lucky
P.S.: Since im new here and this my first qustion please let me know what other specifics you might need or just edit my newby misshabits away.
When you do myFuncThatBadlyNeedsInts((int)c) the compiler first decay the array c to a pointer to the first element, i.e. &c[0], you then cast this pointer to an int and pass that to the function.
When you do *((int*)&c) you take the address of the array (of type int (*)[4]) and tell the compiler that it's a pointer to an int (which is not correct) and then dereference that (incorrect) int*.
So both calls are actually incorrect. The casting just silences the compiler.
If you want to treat the four bytes of the array as a single 32-bit word, there are ways to do it, but they all breaks the strict aliasing rule.
The simplest way is very close to what you have now, and is done with casting. Using C-casting you cast the pointer that c decays to as a pointer to int and dereference that:
myFuncThatBadlyNeedsInts(*(int*)c);
Note that this is not the same thing as either of your attempts.
The second way is to use a union:
union my_union
{
char bytes[sizeof(int)];
int integer;
};
Then copy the data to your unions bytes member, and read out the integer.
In the first case you are trying to cast an char array to an int - this is obviously meaningless in that an list of characters is quite different to an int.
In The second case you first take the address of the array - the & operator gives you a character pointer to the first element of the array.
Specifically the type of &c is unsigned char * - it is legal (although dangerous) to cast between pointer types thus the cast from unsigned char * to int * is legal.
Then you dereference the pointer and get the integer that is at this spot which is probably some nasty (meaningless) number derived from the first couple of characters in the string which are those bytes.
So you second solution doesn't convert from char[] to int[] which is presumably what you want, instead it give you an integer representation of the first bytes of the char array.
In the second case you get pointer from unsigned char than cast it to integer, so in fact you always use your uchar and 3 bytes just after (in this case whole array c). Because of sizeof int is 4 (usually, but not always), and size of uchar is only 1. So don't do this unless you like to shoot yourself in leg.
To be honest I don't really understand what you are going to achive in this example
Looking at the examples presented by various google results, I don't really understand how the EndPtr works. For an example:
char szOrbits[] = "686.97 365.24";
char* pEnd;
float f1 = strtof (szOrbits, &pEnd);
The function takes the pointer of the pointer that is declared after the char array, does that mean that the actual type and contents of the pointer are irrelevant and the pointer is guaranteed to be allocated right after the array thus making its address the end point?
I tried using it like this:
ret.push_back(EquationPiece(strtof(&Source[mark], (char**)&Source[i])));
where ret is a vector, Source is a char array, mark is where the number begins and i is the next byte after the number but I'm getting some strange results. Is my usage incorrect or should I seek for the bug elsewhere?
Although the reference page describes the parameter pendptr as a reference to a char* object this might be misundestood. In C we have only pointers and the second parameter of strtof is a pointer to a pointer to char.
You can utilize this parameter to get the point in the input char array that could not be used to convert the char array to the output float. If the pointer points to a '\0' than the array has been converted entirely. If it points to something different you can start error handling or further processing of the char array.
You should never cast any pointer when you are not sure what it means. Cast tells the compiler that the programmer knows it better. Depending on the meaning of your EquationPiece it might be useful to pass the endPtr:
ret.push_back(EquationPiece(strtof(&Source[mark], pEnd));
I'm trying to understand a part of my professor's code. He gave an example for a hw assignment but I'm not sure how to understand this part of the code..
Here is the code:
void addTask(TaskOrAssignment tasks[], int& taskCount, char *course, char *description, char *dueDate)
{
tasks[taskCount].course = course;
tasks[taskCount].description = description;
tasks[taskCount].dueDate = dueDate;
taskCount++;
}
Question: Is "tasks[taskCount].course = course;" accessing or declaring a location for char course?
I hope I could get this answered and I'm pretty new to this site too.
Thank you.
tasks[taskCount].course = course;
Let's break this down a piece at a time. First of all, we are using the assignment operator (=) to assign a value of one variable to another variable.
The right hand side is pretty simple, just the variable named course which is declared as a char*.
It is assigned to the variable tasks[taskCount].course. If you look at the parameters of the method, you can see that tasks is declared as an array of TaskOrAssignment objects. So tasks[taskCount] refers to one of the elements of this array. The .course at the end refers to a field named course in that object. Assuming that this code compiles, that field is declared as a char* in the TaskOrAssignment class.
Most likely, both course variables represent a string of characters. (This originates from C.) When all is said and done, both course and tasks[taskCount].course point to the same string buffer.
course is a char pointer, it points to the block of memory in stack or heap storing the '\0' terminated string.
tasks[taskCount].course is also a char pointer, the assignment just lets tasks[taskCount].course point to same memory address that course does.
course is a char* (a pointer to char). Presumably, the course member of TaskOrAssignment is also a char*. All that line does is assign the value of course to the member course of the taskCountth element in the array.
Presumably, the course argument is intended to be a pointer to the first character in a null-terminated C-style string. So after this assignment, the course member of the array element will point at that same C-style string. However, of course, the pointer could really be pointing anywhere.