The parameter argv in the function main(int argc, char *argv[]) - c++

Sorry if this seems like a basic question. I've been studying for a midterm I have coming up and I can't seem to wrap my head around this. I understand that argv can be used in the command line when you need to send it arguments, but none of the answers my professor gave us seems to make sense.
The parameter argv in the function main(int argc, char *argv[]) is:
A. An array of characters
B. A string
C. An array of pointers to character
D. A character pointer
E. None of the above
I feel like it is none of the above, but it could be because I don't fully understand the concept of argv. Any help would be appreciated!

The correct answer is E, none of the above. Although the parameter declaration looks like an array of pointer to char, the rules of C adjust it to pointer to pointer to char, and so do the rules of C++.
Either your instructor mistakenly intended choice C or your instructor designed a question inappropriately tricky for an introductory class, unless it is extra credit.

I think your professor wants C, even though the pedanticly correct answer is E. The data referred to by argv is an array, but the variable itself is a pointer. I think it's worth exploring why, because it has nothing to do with the type of array or main.
Consider an array of integers,
int a[] = { 1, 2, 3 };
This allocates 3 adjacent integers. The size of the array is sizeof(int) * 3.
Now let's write a function to double the values of each member,
void F( int m[], size_t n ) {
for( int i=0; i < n; i++ ) {
m[i] *= 2;
}
int main( int argc, char *argv[] ) {
F(a, sizeof(a)/sizeof(a[0]));
return EXIT_SUCCESS;
}
What is m? It's declared to be an array, but it's really a pointer: sizeof(m) == sizeof(int*). That's because C doesn't pass arrays as function arguments. The term of art in C is that an array argument decays to a pointer.
It sorta kinda doesn't matter, because C syntax hides a host of sins, er, differences. You can use the subscript notation with both arrays and pointers. For that reason, our function F can treat m almost like an array, except that it requires the length, because it can't derive the length from the size, because the size is the size of the pointer.
Let me say that a different way. When F is called, the "arguments on the stack" are not the values of a, namely 1, 2, and 3. There is just one such argument, a pointer to the first element of a (often thought of as the address of the first element). You can use that pointer as an array partly because the name of an array also refers to the address of the first element.
Now let's back up to your friend argv. Array, or pointer? Let's say your program foo is invoked on the command line:
$ foo sam I am
What does the operating system do? Somehow, it has to pass those 4 strings (character arrays) to your program. Somewhere, it has to allocate contiguous space for them. Conceptually, the shell might do something like:
char **args = calloc(5, sizeof(char*));
args[0] = "foo";
args[1] = "sam";
args[2] = "I";
args[3] = "am";
or,
char args[5] = { "foo", "sam", "I", "am" };
Either way, it could pass args to execv(3), invoking your main, and passing you a ... pointer. After all, it can't pass you an array, right?
Please note args must be an array. If it weren't argv[1] would be meaningless.
(Why 5 elements, you ask, when there are only 4 arguments? There's a rule -- C or Posix, i don't remember -- that the last element in the array (!) must be a NULL pointer.)
Array or pointer? Wave or particle? Where you stand depends on where you sit. argv is pointer a to char*, certainly. By definition, though, it's a pointer to the start of an array of char*.

Related

Difference between char** and char*

So I have a 2D array (I think) in my main:
char* map[width][height] = {MATRIX HERE};
And I'm passing it to a function:
bool canAccessEdge (char** map, int size, int currentPosX, int currentPosY);
I'm passing with with via:
canAccessEdge (*map, 10, playerStartPosX, playerStartPosY);
I want to traverse the map array and mark the positions that the player was already on. But I understand I can't change a value at an index in the function.
I understand that char map [][] would be an array and char *map is a pointer. So what is char* map [][]? Is there a work around without changing the prototype?
Sorry if these are dumb questions... I can't grasp pointers/arrays too well.
bool exitPossible (char** map, int size, int currentPosX, int currentPosY) {
...
*maze[currentPosX][currentPosY] = "V"; // Operand of '*' must be a pointer but has type "char"
(&maze)[currentPosX][currentPosY] = "V"; // Changes whole row and not the right position
&(maze)[currentPosX][currentPosY] = "V"; // Expression must be a modifiable lvalue (I assume it's immutable)
...
}
char[N] can degrade to char*. That does not mean that char[N][M] can degrade to char**. Beginners always make this assumption but it is not true.
char*[N][M] is something else again. That is not a 2D array of char (which seems to be what you want). A 2D array of chars is char[N][M]. With a 2D array of chars the correct syntax is
maze[currentPosX][currentPosY] = 'V';
Note the single quotes.
If you want to pass a 2D array of chars to a function then the simplest way is to declare the function with a 2D array of chars
bool exitPossible(char maze[N][M], ...)
but the reality is that maze here is a pointer to a 1D array, it's actually not possible to have an array as a function parameter in C++. So the truthful declaration of the function is
bool exitPossible(char (*maze)[M], ...)
Here we see what maze really is, a pointer to a 1D array (of size M). And this completes the first paragraph above. A 2D array char[N][M] degrades not to char** but to char (*)[M]. If this seems complicated then you are right, a good book is needed to explain it fully.
Note that in all this discussion N and M are constants. In C++ array sizes cannot be variable.

Confusion about argc argv and env

I just don't know how to explain my question precisely. So I wrote that title above.
Here is my confusion about a very simple program. Exactly, the results.
#include <iostream>
using namespace std;
char * tmp[]={"aaa", "bbb", "ccc"};//there are 3 members
int main(int argc, char* argv[], char* env[])
{
cout << sizeof(env)/sizeof(char*) << endl;
cout << sizeof(tmp)/sizeof(char*) << endl;
}
Results:1 3
What I want is the length of env[]. How can this possible that I got number 1 of env[], while the length of 'tmp'(3) is absolutely rigth.
There's no way that the length of env is 1, cause I tested it and the number is 47.
Why this happened?
Thanks!
The difference is that tmp is an array, whereas env is a pointer. Arrays and pointers are different. It's a bit confusing because array syntax in a function formal parameter list is actually a pointer in disguise.
There is no way to get the number of elements pointed to by env using sizeof. You have to go through them until you find the NULL element terminating the list.
The important thing to remember is that argv and env are pointers, not arrays. In the context of a function parameter declaration, T a[] and T a[N] are interpreted as T *a, so the types of both argv and env are char **, not char *[N].
The only way to determine how many elements each points to is by iterating through them until you find a NULL pointer:
size_t i;
for ( i = 0; argv[i] != NULL; i++ )
; // empty loop body
printf( "There are %zu elements in argv\n", i );
for ( i = 0; env[i] != NULL; i++ )
; // empty loop body
printf( "There are %zu elements in env\n", i );
The language C has certain syntactical features that are convenient for the experienced programmer, but confusing for the new learner. While the syntax T * X[] looks the same in your two cases, they actually mean two very different things:
int a[] = { 1, 2, 3}; is the same as int a[3] = { 1, 2, 3 };. Here a is an array, and the size of the array is deduced from the initializer.
void f(int b[]) is the same as void f(int * b). Here b is a pointer, and the notation is merely suggestive of the fact that you should call f with a pointer to an element of an array. For instance, you could call f(a), or equivalently f(&a[0]), or even f(a + 2). But the declarator syntax is purely a cosmetic convenience, and b is not an array, but a pointer.
This has little to do with these being parameters to main, sizeof anything is a compile time expression. Obviously, the environment and arguments passed to your program aren't. sizeof(array)/sizeof(element_type) is only the length of the array if that array was declared with a static size. Otherwise, sizeof(array) will be equivalent to sizeof(element*) (and because sizeof(char**) == sizeof(char*) you get 1 in your program).

C++ static_cast from int* to void* to char* - can you help me to understand this code?

I'm a beginner in C++, and I have problem with understanding some code.
I had an exercise to do, to write function which returns size of int, and do not use sizeof() and reinterpret_cast. Someone gave me solution, but I do not understand how it works. Can you please help me to understand it? This is the code:
int intSize() {
int intArray[10];
int * intPtr1;
int * intPtr2;
intPtr1 = &intArray[1];
intPtr2 = &intArray[2];
//Why cast int pointer to void pointer?
void* voidPtr1 = static_cast<void*>(intPtr1);
//why cast void pointer to char pointer?
char* charPtr1 = static_cast<char*>(voidPtr1);
void* voidPtr2 = static_cast<void*>(intPtr2);
char* charPtr2 = static_cast<char*>(voidPtr2);
//when I try to print 'charPtr1' there is nothing printed
//when try to print charPtr2 - charPtr1, there is correct value shown - 4, why?
return charPtr2 - charPtr1;
}
To summarize what I don't understand is, why we have to change int* to void* and then to char* to do this task? And why we have the result when we subtract charPtr2 and charPtr1, but there is nothing shown when try to print only charPtr1?
First of all, never do this in real-world code. You will blow off your leg, look like an idiot and all the cool kids will laugh at you.
That being said, here's how it works:
The basic idea is that the size of an int is equal to the offset between two elements in an int array in bytes. Ints in an array are tightly packed, so the beginning of the second int comes right after the end of the first one:
int* intPtr1 = &intArray[0];
int* intPtr2 = &intArray[1];
The problem here is that when subtracting two int pointers, you won't get the difference in bytes, but the difference in ints. So intPtr2 - intPtr1 is 1, because they are 1 int apart.
But we are in C++, so we can cast pointers to anything! So instead of using int pointers, we copy the value to char pointers, which are 1 byte in size (at least on most platforms).
char* charPtr1 = reinterpret_cast<char*>(intPtr1);
char* charPtr2 = reinterpret_cast<char*>(intPtr2);
The difference charPtr2 - charPtr1 is the size in bytes. The pointers still point to the same location as before (i.e. the start of the second and first int in the array), but the difference will now be calculated in sizes of char, not in sizes of int.
Since the exercise did not allow reinterpret_cast you will have to resort to another trick. You cannot static_cast from int* to char* directly. This is C++'s way of protecting you from doing something stupid. The trick is to cast to void* first. You can static_cast any pointer type to void* and from void* to any pointer type.
This is the important bit:
intPtr1 = &intArray[1];
intPtr2 = &intArray[2];
This creates two pointers to adjacent ints in the array. The distance between these two pointers is the size of an integer that you're trying to retrieve. However the way that pointer arithmetic works is that if you subtract these two then the compiler will return you the size in terms of ints, which will always be 1.
So what you're doing next is re-casting these as character pointers. Characters are (or de-facto are) 1 byte each, so the difference between these two pointers as character pointers will give you an answer in bytes. That's why you're casting to character pointers and subtracting.
As for via void* - this is to avoid having to use reinterpret_cast. You're not allowed to cast directly from a int* to a char* with static_cast<>, but going via void* removes this restriction since the compiler no longer knows it started with an int*. You could also just use a C-style cast instead, (char*)(intPtr1).
"do not use sizeof() and reinterpret_cast"... nothing's said about std::numeric_limits, so you could do it like that :)
#include <limits>
int intSize()
{
// digits returns non-sign bits, so add 1 and divide by 8 (bits in a byte)
return (std::numeric_limits<int>::digits+1)/8;
}
Pointer subtraction in C++ gives the number of elements between
the pointed to objects. In other words, intPtr2 - intPtr1
would return the number of int between these two pointers.
The program wants to know the number of bytes (char), so it
converts the int* to char*. Apparently, the author doesn't
want to use reinterpret_cast either. And static_cast will
not allow a direct convertion from int* to char*, so he
goes through void* (which is allowed).
Having said all that: judging from the name of the function and
how the pointers are actually initialized, a much simpler
implementation of this would be:
int
intSize()
{
return sizeof( int );
}
There is actually no need to convert to void*, other than avoiding reinterpret_cast.
Converting from a pointer-to-int to a pointer-to-char can be done in one step with a reinterpret_cast, or a C-style cast (which, by the standard, ends up doing a reinterpret_cast). You could do a C-style cast directly, but as that (by the standard) is a reinterpret_cast in that context, you'd violate the requirements. Very tricky!
However, you can convert from an int* to a char* through the void* intermediary using only static_cast. This is a small hole in the C++ type system -- you are doing a two-step reinterpret_cast without ever calling it -- because void* conversion is given special permission to be done via static_cast.
So all of the void* stuff is just to avoid the reinterpret_cast requirement, and would be silly to do in real code -- being aware you can do it might help understanding when someone did it accidentally in code (ie, your int* appears to be pointing at a string: how did that happen? Well, someone must have gone through a hole in the type system. Either a C-style cast (and hence a reinterpret_cast), or it must have round-tripped through void* via static_cast).
If we ignore that gymnastics, we now have an array of int. We take pointers to adjacent elements. In C++, arrays are packed, with the difference between adjacent elements equal to the sizeof the elements.
We then convert those pointers to pointers-to-char, because we know (by the standard) that sizeof(char)==1. We subtract these char pointers, as that tells us how many multiples-of-sizeof(char) there are between them (if we subtract int pointers, we get how many multiples-of-sizeof(int) there are between them), which ends up being the size of the int.
If we try to print charPtr1 through std::cout, std::cout assumes that our char* is a pointer-to-\0-terminated-buffer-of-char, due to C/C++ convention. The first char pointed to is \0, so std::cout prints nothing. If we wanted to print the pointer value of the char*, we'd have to cast it to something like void* (maybe via static_cast<void*>(p)).
Please read this: richly commented.
int intSize()
{
int intArray[2]; // Allocate two elements. We don't need any more than that.
/*intPtr1 and intPtr2 point to the addresses of the zeroth and first array elements*/
int* intPtr1 = &intArray[0]; // Arrays in C++ are zero based
int* intPtr2 = &intArray[1];
/*Note that intPtr2 - intPtr1 measures the distance in memory
between the array elements in units of int*/
/*What we want to do is measure that distance in units of char;
i.e. in bytes since once char is one byte*/
/*The trick is to cast from int* to char*. In c++ you need to
do this via void* if you are not allowed to use reinterpret_cast*/
void* voidPtr1 = static_cast<void*>(intPtr1);
char* charPtr1 = static_cast<char*>(voidPtr1);
void* voidPtr2 = static_cast<void*>(intPtr2);
char* charPtr2 = static_cast<char*>(voidPtr2);
/*The distance in memory will now be measure in units of char;
that's how pointer arithmetic works*/
/*Since the original array is a contiguous memory block, the
distance will be the size of each element, i.e. sizeof(int) */
return charPtr2 - charPtr1;
}

Difference between passing array, fixed-sized array and base address of array as a function parameter

I am confused about which syntax to use if I want to pass an array of known or unknown size as a function parameter.
Suppose I have these variants for the purpose:
void func1(char* str) {
//print str
}
void func2(char str[]) {
//print str
}
void func3(char str[10]) {
//print str
}
What are the pros and cons of using each one of these?
All these variants are the same. C just lets you use alternative spellings but even the last variant explicitly annotated with an array size decays to a normal pointer.
That is, even with the last implementation you could call the function with an array of any size:
void func3(char str[10]) { }
func("test"); // Works.
func("let's try something longer"); // Not a single f*ck given.
Needless to say this should not be used: it might give the user a false sense of security (“oh, this function only accepts an array of length 10 so I don’t need to check the length myself”).
As Henrik said, the correct way in C++ is to use std::string, std::string& or std::string const& (depending on whether you need to modify the object, and whether you want to copy).
Note that in C++, if the length of the array is known at compile time (for example if you passed a string literal), you can actually get its size:
template<unsigned int N>
void func(const char(&str)[N])
{
// Whatever...
}
int main()
{
func("test"); // Works, N is 5
}
In C++, use void func4(const std::string& str).
These are all functionally identical. When you pass an array to a function in C, the array gets implicitly converted to a pointer to the first element of the array. Hence, these three functions will print the same output (that is, the size of a pointer to char).
void func1(char* str) {
printf("sizeof str: %zu\n", sizeof str);
}
void func2(char str[]) {
printf("sizeof str: %zu\n", sizeof str);
}
void func3(char str[10]) {
printf("sizeof str: %zu\n", sizeof str);
}
This conversion only applies to the first dimension of an array. A char[42][13] gets converted to a char (*)[13], not a char **.
void func4(char (*str_array)[13]) {
printf("sizeof str_array: %zu\n"
"sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}
char (*)[13] is the type of str_array. It's how you write "a pointer to an array of 13 chars". This could have also been written as void func4(char str_array[42][13]) { ... }, though the 42 is functionally meaningless as you can see by experimenting, passing arrays of different sizes into func4.
In C99 and C11 (but not C89 or C++), you can pass a pointer to an array of varying size into a function, by passing it's size along with it, and including the size identifier in the [square brackets]. For example:
void func5(size_t size, char (*str_array)[size]) {
printf("sizeof str_array: %zu\n"
"sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}
This declares a pointer to an array of size chars. Note that you must dereference the pointer before you can access the array. In the example above, sizeof str_array[0] evaluates to the size of the array, not the size of the first element. As an example, to access the 11th element, use (*str_array)[11] or str_array[0][11].
In C, the first two definitions are equivalent.The third one is essentially same but it gives an idea about the size of the array.
If printing str is your intent, then you can safely use any of them.Essentially all three of the functions are passed a parameter of type char*,just what printf() needs to print a string.And lest you don't know, despite what it may seem, all parameter passing in C is done in pass-by-value mode.
Edit: Seems like I'll have to be very rigorous in my choice of words on SO henceforth.Well,in the third case it gives no idea about the size of the array to the function to which it is passed as eventually it is reduced to type char* just as in the first two cases.I meant to say it kinda tells the human reading it that the array's size is 10.Also,it is not wrong/illegal in C.But for the program,doing it is as good as useless.It gives no idea whatsoever about the array size to the function it is passed to.Mr.Downvoter, thanks for pointing out that casual attitude and negligence is not tolerated on SO.
In a one dimensional array they are all treated the same by the compiler. However for a two or more dimensional array, (e.g. myArray[10][10]), it is useful as it can be used to determine the row/column length of an array.
To add-on, describing in points.
1) As everyone told it is same.
2) Arrays are decayed into pointers when they are passed in the function arguments.
3) Fundamental problem could be finding the size of a array in the function. For that we can use macro like.
#define noOfElements(v) sizeof(v)/sizeof(0[v])
int arr[100]
myfunction ( arr, noOfElements(arr))
either 0[v] or v[0] can be used in the macro, where the first is used to avoid user defined data type passed in to noOfElements.
Hope this helps.

How do I find the length of "char *" array in C?

I declare the following array:
char* array [2] = { "One", "Two"};
I pass this array to a function. How can I find the length of this array in the function?
You can't find the length of an array after you pass it to a function without extra effort. You'll need to:
Use a container that stores the size, such as vector (recommended).
Pass the size along with it. This will probably require the least modification to your existing code and be the quickest fix.
Use a sentinel value, like C strings do1. This makes finding the length of the array a linear time operation and if you forget the sentinel value your program will likely crash. This is the worst way to do it for most situations.
Use templating to deduct the size of the array as you pass it. You can read about it here: How does this Array Size Template Work?
1 In case you were wondering, most people regret the fact that C strings work this way.
When you pass an array there is NOT an easy way to determine the size within the function.
You can either pass the array size as a parameter
or
use std::vector<std::string>
If you are feeling particularly adventurous you can use some advanced template techniques
In a nutshell it looks something like
template <typename T, size_t N>
void YourFunction( T (&array)[N] )
{
size_t myarraysize = N;
}
C is doing some trickery behind your back.
void foo(int array[]) {
/* ... */
}
void bar(int *array) {
/* ... */
}
Both of these are identical:
6.3.2.1.3: Except when it is the operand of the sizeof operator or the unary & operator,
or is a string literal used to initialize an array, an expression that has type
‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’
that points to the initial element of the array object and is not an lvalue. If
the array object has register storage class, the behavior is undefined.
As a result, you don't know, inside foo() or bar(), if you were
called with an array, a portion of an array, or a pointer to a single
integer:
int a[10];
int b[10];
int c;
foo(a);
foo(&b[1]);
foo(&c);
Some people like to write their functions like: void foo(int *array)
just to remind themselves that they weren't really passed an array,
but rather a pointer to an integer and there may or may not be more
integers elsewhere nearby. Some people like to write their functions
like: void foo(int array[]), to better remind themselves of what the
function expects to be passed to it.
Regardless of which way you like to do it, if you want to know how long
your array is, you've got a few options:
Pass along a length paramenter too. (Think int main(int argc, char
*argv)).
Design your array so every element is non-NULL, except the last
element. (Think char *s="almost a string"; or execve(2).)
Design your function so it takes some other descriptor of the
arguments. (Think printf("%s%i", "hello", 10); -- the string describes
the other arguments. printf(3) uses stdarg(3) argument handling, but
it could just as easily be an array.)
Getting the array-size from the pointer isn't possible. You could just terminate the array with a NULL-pointer. That way your function can search for the NULL-pointer to know the size, or simply just stop processing input once it hits the NULL...
If you mean how long are all the strings added togather.
int n=2;
int size=0;
char* array [n] = { "One", "Two"};
for (int i=0;i<n;++i)
size += strlen(array[i];
Added:
yes thats what im currently doing but i wanted to remove that extra
paramater. oh well –
Probably going to get a bad response for this, but you could always use the first pointer to store the size, as long as you don't deference it or mistake it for actually being a pointer.
char* array [] = { (char*)2,"One", "Two"};
long size=(long)array[0];
for(int i=1; i<= size;++i)
printf("%s",array[i]);
Or you could NULL terminate your array
char* array [] = { "One", "Two", (char*)0 };
for(int i=0;array[i]!=0;++i)
{
printf("%s",array[i]);
}
Use the new C++11 std::array
http://www.cplusplus.com/reference/stl/array/
the standard array has the size method your looking for