Why C/C++ main argv is declared as “char* argv[]” rather than just “char* argv”
Why is argv
declared as "a pointer to pointer to the first index of the array", rather than just being "a pointer to the first index of array" (char* argv
), why is the notion of "pointer to pointer" required here?
c++ c
New contributor
add a comment |
Why is argv
declared as "a pointer to pointer to the first index of the array", rather than just being "a pointer to the first index of array" (char* argv
), why is the notion of "pointer to pointer" required here?
c++ c
New contributor
1
"a pointer to pointer to the first index of the array" - That's not a correct description ofchar* argv
orchar**
. That's a pointer to a pointer to a character; specifically the outer pointer points to the first pointer in an array, and the inner pointers point to the first characters of nul-terminated strings. There's no indices involved here.
– Sebastian Redl
1 hour ago
add a comment |
Why is argv
declared as "a pointer to pointer to the first index of the array", rather than just being "a pointer to the first index of array" (char* argv
), why is the notion of "pointer to pointer" required here?
c++ c
New contributor
Why is argv
declared as "a pointer to pointer to the first index of the array", rather than just being "a pointer to the first index of array" (char* argv
), why is the notion of "pointer to pointer" required here?
c++ c
c++ c
New contributor
New contributor
New contributor
asked 7 hours ago
a usera user
112
112
New contributor
New contributor
1
"a pointer to pointer to the first index of the array" - That's not a correct description ofchar* argv
orchar**
. That's a pointer to a pointer to a character; specifically the outer pointer points to the first pointer in an array, and the inner pointers point to the first characters of nul-terminated strings. There's no indices involved here.
– Sebastian Redl
1 hour ago
add a comment |
1
"a pointer to pointer to the first index of the array" - That's not a correct description ofchar* argv
orchar**
. That's a pointer to a pointer to a character; specifically the outer pointer points to the first pointer in an array, and the inner pointers point to the first characters of nul-terminated strings. There's no indices involved here.
– Sebastian Redl
1 hour ago
1
1
"a pointer to pointer to the first index of the array" - That's not a correct description of
char* argv
or char**
. That's a pointer to a pointer to a character; specifically the outer pointer points to the first pointer in an array, and the inner pointers point to the first characters of nul-terminated strings. There's no indices involved here.– Sebastian Redl
1 hour ago
"a pointer to pointer to the first index of the array" - That's not a correct description of
char* argv
or char**
. That's a pointer to a pointer to a character; specifically the outer pointer points to the first pointer in an array, and the inner pointers point to the first characters of nul-terminated strings. There's no indices involved here.– Sebastian Redl
1 hour ago
add a comment |
4 Answers
4
active
oldest
votes
Argv is basically like this:
So on the left is the argument itself--what's actually passed as a parameter to main. That contains the address of an array of pointers. Each of those points to some place in memory containing the text of the corresponding argument that was passed on the command line. Then, at the end of that array there's guaranteed to be a null pointer.
Note that the actual storage for the individual arguments are at least potentially allocated separately from each other, so their addresses in memory might be arranged fairly randomly (but depending on how things happen to be written, they could also be in a single contiguous block of memory--you simply don't know or and shouldn't care).
add a comment |
Because that's what the operating system provides :-)
Your question is a little bit of a chicken/egg inversion issue. The problem is not to choose what you want in C++, the problem is how you say in C++ what the OS is giving you.
Unix passes an array of "strings", each string being a command argument. In C/C++, a string is a "char*", so an array of strings is char* argv, or char** argv, according to taste.
New contributor
add a comment |
First, as a parameter declaration, char **argv
is the same as char *argv
; they both imply a pointer to (an array or set of one or more possible) pointer(s) to strings.
Next, if you only have "pointer to char" (e.g. just char *
, then in order to access the nth item, you'll have to scan the first n-1 items to find the nth item's start. (And this would also impose the requirement that each of the strings are stored contiguously.)
With the array of pointers, you can directly index the nth item — so (while not strictly necessary — assuming the strings are contiguous) it is generally much more convenient.
To illustrate:
./program hello world
argc = 3
argv[0] --> "./program"
argv[1] --> "hello"
argv[2] --> "world"
It is possible that, in string:
"./programhelloworld"
argv[0] ^
argv[1] ^
argv[2] ^
if argv were just a "pointer to char" you might see
"./programhelloworld"
argv ^
However (though likely by design of the os) there is no real guarantee that the three strings "./program", "hello", and "world" are contiguous. Further, this kind of "single pointer to multiple contiguous strings" is a more unusual data type construct (for C), especially compared with array of pointers to string.
what if instead of ,argv --> "helloworld"
you haveargv --> index 0 of the array
(hello), just like a normal array. why isn't this doable? then you keep reading the arrayargc
times. then you pass argv itself and not a pointer to argv.
– a user
7 hours ago
@Erik They are the same thing in a function-declaration, not in general. Just try to declare some external variables.
– Deduplicator
7 hours ago
@auser, that's what argv --> "./programhelloworld" is: a pointer to the first char (i.e. the ".") If you take that pointer past the first , then you have a pointer to "hello", and after that to "world". After argc times (hitting "), you're done. Sure, it can be made to work, and as I said, an unusual construct.
– Erik Eidt
1 hour ago
@Deduplicator, of course, good point.
– Erik Eidt
1 hour ago
You forgot to state that in your exampleargv[4]
isNULL
– Basile Starynkevitch
36 mins ago
|
show 1 more comment
Rather than thinking of it as "pointer to pointer", it helps to think of it as "array of strings", with denoting array and
char*
denoting string. When you run a program, you can pass it one or more command-line arguments and these are reflected in the arguments to main
: argc
is the count of arguments and argv
lets you access individual arguments.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "131"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
a user is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f385819%2fwhy-c-c-main-argv-is-declared-as-char-argv-rather-than-just-char-argv%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Argv is basically like this:
So on the left is the argument itself--what's actually passed as a parameter to main. That contains the address of an array of pointers. Each of those points to some place in memory containing the text of the corresponding argument that was passed on the command line. Then, at the end of that array there's guaranteed to be a null pointer.
Note that the actual storage for the individual arguments are at least potentially allocated separately from each other, so their addresses in memory might be arranged fairly randomly (but depending on how things happen to be written, they could also be in a single contiguous block of memory--you simply don't know or and shouldn't care).
add a comment |
Argv is basically like this:
So on the left is the argument itself--what's actually passed as a parameter to main. That contains the address of an array of pointers. Each of those points to some place in memory containing the text of the corresponding argument that was passed on the command line. Then, at the end of that array there's guaranteed to be a null pointer.
Note that the actual storage for the individual arguments are at least potentially allocated separately from each other, so their addresses in memory might be arranged fairly randomly (but depending on how things happen to be written, they could also be in a single contiguous block of memory--you simply don't know or and shouldn't care).
add a comment |
Argv is basically like this:
So on the left is the argument itself--what's actually passed as a parameter to main. That contains the address of an array of pointers. Each of those points to some place in memory containing the text of the corresponding argument that was passed on the command line. Then, at the end of that array there's guaranteed to be a null pointer.
Note that the actual storage for the individual arguments are at least potentially allocated separately from each other, so their addresses in memory might be arranged fairly randomly (but depending on how things happen to be written, they could also be in a single contiguous block of memory--you simply don't know or and shouldn't care).
Argv is basically like this:
So on the left is the argument itself--what's actually passed as a parameter to main. That contains the address of an array of pointers. Each of those points to some place in memory containing the text of the corresponding argument that was passed on the command line. Then, at the end of that array there's guaranteed to be a null pointer.
Note that the actual storage for the individual arguments are at least potentially allocated separately from each other, so their addresses in memory might be arranged fairly randomly (but depending on how things happen to be written, they could also be in a single contiguous block of memory--you simply don't know or and shouldn't care).
answered 4 hours ago
Jerry CoffinJerry Coffin
40.1k574148
40.1k574148
add a comment |
add a comment |
Because that's what the operating system provides :-)
Your question is a little bit of a chicken/egg inversion issue. The problem is not to choose what you want in C++, the problem is how you say in C++ what the OS is giving you.
Unix passes an array of "strings", each string being a command argument. In C/C++, a string is a "char*", so an array of strings is char* argv, or char** argv, according to taste.
New contributor
add a comment |
Because that's what the operating system provides :-)
Your question is a little bit of a chicken/egg inversion issue. The problem is not to choose what you want in C++, the problem is how you say in C++ what the OS is giving you.
Unix passes an array of "strings", each string being a command argument. In C/C++, a string is a "char*", so an array of strings is char* argv, or char** argv, according to taste.
New contributor
add a comment |
Because that's what the operating system provides :-)
Your question is a little bit of a chicken/egg inversion issue. The problem is not to choose what you want in C++, the problem is how you say in C++ what the OS is giving you.
Unix passes an array of "strings", each string being a command argument. In C/C++, a string is a "char*", so an array of strings is char* argv, or char** argv, according to taste.
New contributor
Because that's what the operating system provides :-)
Your question is a little bit of a chicken/egg inversion issue. The problem is not to choose what you want in C++, the problem is how you say in C++ what the OS is giving you.
Unix passes an array of "strings", each string being a command argument. In C/C++, a string is a "char*", so an array of strings is char* argv, or char** argv, according to taste.
New contributor
New contributor
answered 3 hours ago
passer-bypasser-by
311
311
New contributor
New contributor
add a comment |
add a comment |
First, as a parameter declaration, char **argv
is the same as char *argv
; they both imply a pointer to (an array or set of one or more possible) pointer(s) to strings.
Next, if you only have "pointer to char" (e.g. just char *
, then in order to access the nth item, you'll have to scan the first n-1 items to find the nth item's start. (And this would also impose the requirement that each of the strings are stored contiguously.)
With the array of pointers, you can directly index the nth item — so (while not strictly necessary — assuming the strings are contiguous) it is generally much more convenient.
To illustrate:
./program hello world
argc = 3
argv[0] --> "./program"
argv[1] --> "hello"
argv[2] --> "world"
It is possible that, in string:
"./programhelloworld"
argv[0] ^
argv[1] ^
argv[2] ^
if argv were just a "pointer to char" you might see
"./programhelloworld"
argv ^
However (though likely by design of the os) there is no real guarantee that the three strings "./program", "hello", and "world" are contiguous. Further, this kind of "single pointer to multiple contiguous strings" is a more unusual data type construct (for C), especially compared with array of pointers to string.
what if instead of ,argv --> "helloworld"
you haveargv --> index 0 of the array
(hello), just like a normal array. why isn't this doable? then you keep reading the arrayargc
times. then you pass argv itself and not a pointer to argv.
– a user
7 hours ago
@Erik They are the same thing in a function-declaration, not in general. Just try to declare some external variables.
– Deduplicator
7 hours ago
@auser, that's what argv --> "./programhelloworld" is: a pointer to the first char (i.e. the ".") If you take that pointer past the first , then you have a pointer to "hello", and after that to "world". After argc times (hitting "), you're done. Sure, it can be made to work, and as I said, an unusual construct.
– Erik Eidt
1 hour ago
@Deduplicator, of course, good point.
– Erik Eidt
1 hour ago
You forgot to state that in your exampleargv[4]
isNULL
– Basile Starynkevitch
36 mins ago
|
show 1 more comment
First, as a parameter declaration, char **argv
is the same as char *argv
; they both imply a pointer to (an array or set of one or more possible) pointer(s) to strings.
Next, if you only have "pointer to char" (e.g. just char *
, then in order to access the nth item, you'll have to scan the first n-1 items to find the nth item's start. (And this would also impose the requirement that each of the strings are stored contiguously.)
With the array of pointers, you can directly index the nth item — so (while not strictly necessary — assuming the strings are contiguous) it is generally much more convenient.
To illustrate:
./program hello world
argc = 3
argv[0] --> "./program"
argv[1] --> "hello"
argv[2] --> "world"
It is possible that, in string:
"./programhelloworld"
argv[0] ^
argv[1] ^
argv[2] ^
if argv were just a "pointer to char" you might see
"./programhelloworld"
argv ^
However (though likely by design of the os) there is no real guarantee that the three strings "./program", "hello", and "world" are contiguous. Further, this kind of "single pointer to multiple contiguous strings" is a more unusual data type construct (for C), especially compared with array of pointers to string.
what if instead of ,argv --> "helloworld"
you haveargv --> index 0 of the array
(hello), just like a normal array. why isn't this doable? then you keep reading the arrayargc
times. then you pass argv itself and not a pointer to argv.
– a user
7 hours ago
@Erik They are the same thing in a function-declaration, not in general. Just try to declare some external variables.
– Deduplicator
7 hours ago
@auser, that's what argv --> "./programhelloworld" is: a pointer to the first char (i.e. the ".") If you take that pointer past the first , then you have a pointer to "hello", and after that to "world". After argc times (hitting "), you're done. Sure, it can be made to work, and as I said, an unusual construct.
– Erik Eidt
1 hour ago
@Deduplicator, of course, good point.
– Erik Eidt
1 hour ago
You forgot to state that in your exampleargv[4]
isNULL
– Basile Starynkevitch
36 mins ago
|
show 1 more comment
First, as a parameter declaration, char **argv
is the same as char *argv
; they both imply a pointer to (an array or set of one or more possible) pointer(s) to strings.
Next, if you only have "pointer to char" (e.g. just char *
, then in order to access the nth item, you'll have to scan the first n-1 items to find the nth item's start. (And this would also impose the requirement that each of the strings are stored contiguously.)
With the array of pointers, you can directly index the nth item — so (while not strictly necessary — assuming the strings are contiguous) it is generally much more convenient.
To illustrate:
./program hello world
argc = 3
argv[0] --> "./program"
argv[1] --> "hello"
argv[2] --> "world"
It is possible that, in string:
"./programhelloworld"
argv[0] ^
argv[1] ^
argv[2] ^
if argv were just a "pointer to char" you might see
"./programhelloworld"
argv ^
However (though likely by design of the os) there is no real guarantee that the three strings "./program", "hello", and "world" are contiguous. Further, this kind of "single pointer to multiple contiguous strings" is a more unusual data type construct (for C), especially compared with array of pointers to string.
First, as a parameter declaration, char **argv
is the same as char *argv
; they both imply a pointer to (an array or set of one or more possible) pointer(s) to strings.
Next, if you only have "pointer to char" (e.g. just char *
, then in order to access the nth item, you'll have to scan the first n-1 items to find the nth item's start. (And this would also impose the requirement that each of the strings are stored contiguously.)
With the array of pointers, you can directly index the nth item — so (while not strictly necessary — assuming the strings are contiguous) it is generally much more convenient.
To illustrate:
./program hello world
argc = 3
argv[0] --> "./program"
argv[1] --> "hello"
argv[2] --> "world"
It is possible that, in string:
"./programhelloworld"
argv[0] ^
argv[1] ^
argv[2] ^
if argv were just a "pointer to char" you might see
"./programhelloworld"
argv ^
However (though likely by design of the os) there is no real guarantee that the three strings "./program", "hello", and "world" are contiguous. Further, this kind of "single pointer to multiple contiguous strings" is a more unusual data type construct (for C), especially compared with array of pointers to string.
edited 1 hour ago
answered 7 hours ago
Erik EidtErik Eidt
22.7k43158
22.7k43158
what if instead of ,argv --> "helloworld"
you haveargv --> index 0 of the array
(hello), just like a normal array. why isn't this doable? then you keep reading the arrayargc
times. then you pass argv itself and not a pointer to argv.
– a user
7 hours ago
@Erik They are the same thing in a function-declaration, not in general. Just try to declare some external variables.
– Deduplicator
7 hours ago
@auser, that's what argv --> "./programhelloworld" is: a pointer to the first char (i.e. the ".") If you take that pointer past the first , then you have a pointer to "hello", and after that to "world". After argc times (hitting "), you're done. Sure, it can be made to work, and as I said, an unusual construct.
– Erik Eidt
1 hour ago
@Deduplicator, of course, good point.
– Erik Eidt
1 hour ago
You forgot to state that in your exampleargv[4]
isNULL
– Basile Starynkevitch
36 mins ago
|
show 1 more comment
what if instead of ,argv --> "helloworld"
you haveargv --> index 0 of the array
(hello), just like a normal array. why isn't this doable? then you keep reading the arrayargc
times. then you pass argv itself and not a pointer to argv.
– a user
7 hours ago
@Erik They are the same thing in a function-declaration, not in general. Just try to declare some external variables.
– Deduplicator
7 hours ago
@auser, that's what argv --> "./programhelloworld" is: a pointer to the first char (i.e. the ".") If you take that pointer past the first , then you have a pointer to "hello", and after that to "world". After argc times (hitting "), you're done. Sure, it can be made to work, and as I said, an unusual construct.
– Erik Eidt
1 hour ago
@Deduplicator, of course, good point.
– Erik Eidt
1 hour ago
You forgot to state that in your exampleargv[4]
isNULL
– Basile Starynkevitch
36 mins ago
what if instead of ,
argv --> "helloworld"
you have argv --> index 0 of the array
(hello), just like a normal array. why isn't this doable? then you keep reading the array argc
times. then you pass argv itself and not a pointer to argv.– a user
7 hours ago
what if instead of ,
argv --> "helloworld"
you have argv --> index 0 of the array
(hello), just like a normal array. why isn't this doable? then you keep reading the array argc
times. then you pass argv itself and not a pointer to argv.– a user
7 hours ago
@Erik They are the same thing in a function-declaration, not in general. Just try to declare some external variables.
– Deduplicator
7 hours ago
@Erik They are the same thing in a function-declaration, not in general. Just try to declare some external variables.
– Deduplicator
7 hours ago
@auser, that's what argv --> "./programhelloworld" is: a pointer to the first char (i.e. the ".") If you take that pointer past the first , then you have a pointer to "hello", and after that to "world". After argc times (hitting "), you're done. Sure, it can be made to work, and as I said, an unusual construct.
– Erik Eidt
1 hour ago
@auser, that's what argv --> "./programhelloworld" is: a pointer to the first char (i.e. the ".") If you take that pointer past the first , then you have a pointer to "hello", and after that to "world". After argc times (hitting "), you're done. Sure, it can be made to work, and as I said, an unusual construct.
– Erik Eidt
1 hour ago
@Deduplicator, of course, good point.
– Erik Eidt
1 hour ago
@Deduplicator, of course, good point.
– Erik Eidt
1 hour ago
You forgot to state that in your example
argv[4]
is NULL
– Basile Starynkevitch
36 mins ago
You forgot to state that in your example
argv[4]
is NULL
– Basile Starynkevitch
36 mins ago
|
show 1 more comment
Rather than thinking of it as "pointer to pointer", it helps to think of it as "array of strings", with denoting array and
char*
denoting string. When you run a program, you can pass it one or more command-line arguments and these are reflected in the arguments to main
: argc
is the count of arguments and argv
lets you access individual arguments.
add a comment |
Rather than thinking of it as "pointer to pointer", it helps to think of it as "array of strings", with denoting array and
char*
denoting string. When you run a program, you can pass it one or more command-line arguments and these are reflected in the arguments to main
: argc
is the count of arguments and argv
lets you access individual arguments.
add a comment |
Rather than thinking of it as "pointer to pointer", it helps to think of it as "array of strings", with denoting array and
char*
denoting string. When you run a program, you can pass it one or more command-line arguments and these are reflected in the arguments to main
: argc
is the count of arguments and argv
lets you access individual arguments.
Rather than thinking of it as "pointer to pointer", it helps to think of it as "array of strings", with denoting array and
char*
denoting string. When you run a program, you can pass it one or more command-line arguments and these are reflected in the arguments to main
: argc
is the count of arguments and argv
lets you access individual arguments.
answered 7 hours ago
casablancacasablanca
69437
69437
add a comment |
add a comment |
a user is a new contributor. Be nice, and check out our Code of Conduct.
a user is a new contributor. Be nice, and check out our Code of Conduct.
a user is a new contributor. Be nice, and check out our Code of Conduct.
a user is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Software Engineering Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f385819%2fwhy-c-c-main-argv-is-declared-as-char-argv-rather-than-just-char-argv%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
"a pointer to pointer to the first index of the array" - That's not a correct description of
char* argv
orchar**
. That's a pointer to a pointer to a character; specifically the outer pointer points to the first pointer in an array, and the inner pointers point to the first characters of nul-terminated strings. There's no indices involved here.– Sebastian Redl
1 hour ago