I create a clone of the echo command and that's more complicated than I was thinking.
Here my problem :
How works a char *argv[]? I know how works char myString[], but no that weird way to create strings :
It's a pointer on an array of chars, or an array of pointers on chars?
Why when I *argv[n], it shows me the n argument, not the n char... Chars can ve
char* argv[] behaves just like char** argv would behave. You could also use an char argv[][] the same way.
So basically, when you call *argv, you get argv[0] and *argv[n] gives you argv[0][n]
edit: to convert argv[x] into a std::string:
std::string s(argv[x]);
from that point on s is a standard string. But keep in mind that you must have zero terminated strings, this will not work for random binary data in a char**!
It's a pointer on an array of chars, or an array of pointers on chars?
In C, arrays are always passed as pointer to the first element. So, effectively you can treat it as char**, which is a pointer to pointer of char.
Why when I *argv[n], it shows me the n argument, not the n char... Chars can ve
You can split that expression according to the operator precedence:
char* p = argv[n];
char c = *p;
Related
I'm confused about the way C handles strings and char * vs char[].
char name[10] = "asd";
printf("%p\n%p", &name, &name[0]); //0x7ffed617acd
//0x7ffed617acd
If this code gives the same addresses for both arguments, does it mean that the C compiler takes char arrays (strings) as a pointer to the first char in the array and moves in the memory till it gets the null terminator? Why wouldn't the same happen if we changed the char name[] to char *name? (I know they differ but what makes C take both in a different way?)
I know that arrays can't be assigned after declaration (unless you used something like strcpy, strcat) which is also confusing. Why wouldn't C take them as any other data type? (Something tells me the compiler has a specific addr for it while you can assign char* to whatever location in the mem since its a pointer).
I know that char * have fixed size unlike char[] which makes char * not usable for first argument of strcat.
in C a "string" is an array of type "char" (terminated with \0).
When you are referring to an array in C, you are using a pointer to the first element. In this case (char *).
According to the ANSI-C standard the name of an array is a pointer to the first element.
Being able to write name instead of &name[0] is syntactical sugar.
In the same way accessing an array element writing name[i] is analogue to writing *(name+i).
does it mean that the c compiler takes char arrays (strings) as a pointer to the first char in the array
An array is not a pointer. But an array will implicitly convert to a pointer to first element. Such conversion is called "decaying".
... and moves in the memory till it gets the null terminator???
You can write such loop if you know the pointer is to an element of null terminated string. If you write that loop, then the compiler will produce a program that does such thing.
Why wouldn't the same happen if we changed the char name[] to char *name?
Your premise is faulty. You can iterate an array directly, as well as using a pointer.
If this code gives the same addresses for both arguments, does it mean
The address of an object is the first byte of the object. What this "same address" means is that the first byte of the first element of the array is in the same address as the first byte of the array as a whole.
I know that arrays can't be assigned after declaration (unless you used something like strcpy, strcat) which is also confusing.
Neither strcpy nor strcat assign an array. They assign elements of the array which you can also do without calling those functions.
Why wouldn't C take them as any other data type?
This question is unclear. What do you mean by "C taking them"? Why do you think C should take another data type? Which data type do you think it should take?
char name[10] = "asd";
printf("%p\n%p", &name, &name[0]);
The arguments are of type char(*)[10] and char* respectively. The %p format specifier requires that the argument is of type similar to void* which isn't similar to those arguments. Passing an argument of a type other than required by the format specifier results in undefined behaviour. You should cast other pointer types to void* when using %p.
I'm having a problem casting, so is there a way to cast a type of:
char *result;
to a type of
char *argv[100];
?
If so, how would I do this or is there a safe way to do this?
char * result is a string
and
char * argv[100] is array of strings.
You cannot convert string into array of strings. However, you can create an array of strings where the first array value is result.
argv[0] = result;
char *result is a pointer to a char
char *argv[100] is an array of char *, so really it's a char ** (a pointer to pointers)
Keep this in mind:
int* arr[8]; // An array of int pointers.
int (*arr)[8]; // A pointer to an array of integers
This being the case, this is probably not what you want to be doing. I suppose the next question is: What were you trying to do? Or why?
What does result contain, and what do you expect argv to contain after the conversion?
For example, if result points to a list of strings separated by a delimiter, like "foo,bar,bletch,blurga,.., and you want each string to be a separated element in argv, like
argv[0] == "foo"
argv[1] == "bar"
argv[2] == "bletch"
argv[4] == "blurga"
then you could not accomplish this with a simple cast; you'd have to actually scan result and assign individual pointers to argv.
First, a short explanation:
char *result;
The variable result is a pointer and when set it will point to a single character. However, as you know, a single character can be the start of a string that ends with the null (\0) character.
In C, a good programmer can use the pointer result to index through a string.
However, the string's length is NOT known until the pointer reaches a null character.
It is possible to define a fixed length string of characters, in this case code:
char s[100];
Now, the fun begins. s per Kernighan and Ritchie (K&R) is a pointer to a string of characters terminated with a 0.
So, you can code:
s[0] = 'a';
*s = 'a';
s[1] = 'b';
*(s+1) = 'b';
These are equivalent statements.
As mentioned in other posts, let's add explicit parens to your argv statement:
char *(argv[100]);
Thus, this is an array of 100 pointers to characters (each of which might or might not be the start of a string of characters).
Why are pointers to arrays of chars (ie. strings) written as below:
char *path
Instead of:
char *path[]
or something like that?
How could I create a pointer to a char and not a string?
char *path is not a pointer to a string, it is a pointer to a char.
It may be the case that char *path semantically points to a "string", but that is just in the interpretation of the data.
In c, strings often use char *, but only under the assumption that the pointer is to the first character of the string, and the other characters are subsequent in memory until you reach a null terminator. That does not change the fact that it is just a pointer to a character.
char *path is a pointer to char. It can be used to point at a single char as well as to point at a char in a zero-terminated array (a string)
char *path[] is an array of pointers to char.
A pointer to an array of char would be char (*path)[N] where N (the size of the array) is part of the pointer's type. Such pointers are not widely used because the size of the array would have to be known at compile time.
char *path[] is an array of pointers. char *path is a single pointer.
How could I create a pointer to a char and not a string?
A 'string' in C is simply a pointer to a char that has the convention of being the start of a sequence of characters that ends in '\0'. You can declare a pointer to a single char the same way, you just have to take care to use it according to the data it's actually pointing to.
This is similar to the concept that a char in C is just an integer with a rather limited range. You can use that data type as a number, as a true/false value, or as a character that should be displayed as a glyph at some point. The interpretation of what's in the char variable is up to the programmer.
Not having a first class, full-fledged 'string' data type is something that distinguishes C from most other high level languages. I'll let you decide for yourself whether it distinguishes C in a good or a bad way.
I'm learning c programming, and I don't understand what is this asterisk for in the main method.
int main(int argc, char* argv[])
char* a; means that a is a pointer to variable of type char.
In your case argv is a pointer to a pointer (or even several of them - it is specified in argv in your case) to a variable(s) of type char. In other words, it's a pointer to an array (of length argv) of pointers to char variables.
You can even write your code this way: int main(int argc, char** argv) and nothing, actually, changes as soon as char* a is the same as char a[].
It means that argv is an array of character pointers.
The declaration char *argv[] declares argv as an array (of unknown size) of pointer to char.
For any type T, the declaration
T *p;
declares p as a pointer to T. Note that the * is bound to the identifier, not the type; in the declaration
T *a, b;
only a is declared as a pointer.
It signifies a pointer. char argv[] declares an array of characters. char* argv[] declares an array of character pointers, or pointers to strings.
Those are parameters passed from the command line to your program. This asterix is a pointer operator.
Basically char argv[] is an array of characters, char *argv[] is a pointer to an array of characters. So it is here to represent multiple strings to put it simply!
Note that: char *argv[] is equivalent to char * * argv, as char argv[] could be represented as char *argv.
Just to go further you would be amazed that those two expressions are equivalent:
int a[5];
int 5[a];
This is because an array of integers is a pointer to a set of integers in memory.
So a[1] can be represented as *(a + 1), a[2] as *(a + 2) etc. Which is equivalent to *(1 + a) or *(2 + a).
Anyway, pointers are like one of the most important and difficult notion to grasp when starting programming in C so I would suggest you taking a serious look at it on Google!
This " * " over here is, for sure to specify a pointer only, to place the argv[] //variable number of argument values// to a place it can fit.
Cause you don't know how many parameters will the user be passing as it is argc [argument count] and argv [argument value]. But we do want to allocate them a space where they can fit so we use a pointer with no defined specific SIZE, this pointer will automaticaly find and fit to appropriate memory location.
Hope this helped, if this didn't I'll be glad to help just let me know :)
Does ** have any special meaning in C?
Like this:
static intparse_one (int argc, char **argv)
{
cmd_line *slot;
int value;
Flag_name flag_name;
int i;
printf("argv %s\n",argv);
printf("argv[0] %c\n",**argv);
If so, does the line
**argv
make sense? A program I am trying to get to run is choking on it. If I try to print it I get a segmentation fault.
The first printf prints the string fine. The second printf fails.
Here is what I am getting for the output (The first line is correct):
argv -aps_instance1001-aps_ato0-aps_ipc_debug3
Segementation Fault (core dumped)
"Does ** have any special meaning in C?"
No, it is just two dereferences.
char **argv
means: argv dereferenced two times is a char. In other words argv is a pointer to a pointer to char.
The same for:
"If so, does the line: **argv make sense?"
The declaration says that **argv is a char. At runtime argv will be dereferenced two times; the value is the char that argv, the pointer to a pointer to char, is pointing to.
** is just two *.
As far as the segfault goes, look at your line printf("argv %s\n",argv);. The printf expects a char *, not char **, and so it's looking at an array of pointers rather than an array of characters. printf is trying to print everything at argv as a string of characters until it encounters a zero, and probably goes out of bounds before it finds one.
argv is a char **, which is a pointer to a pointer, or in this case an array of pointers. Don't print it directly, because it has no external meaning. (You can print the pointer value if you want to see it, of course.)
*argv or argv[0] is a char *, which is a pointer to char, which in this case is the first string in argv.
**argv is a char, which in this case is the first character of the first string in argv.
Yes.
char **argv
is the same thing as
char* argv[]
No.
Every * introduces a level of indirection. In this context, it means that argv is a pointer to a pointer. Which it is not, really, as technically you can see it a an array of pointers - it can be declared as char * argv[].
Obviously, by "no", I mean that ** is not special in itself. Or it is special, but neither more nor less than * or ***.
char **argv is same as char *argv[].
Here argv is the argument vector.
Isn't that a pointer to a pointer? I think the ** in front of the argv parameter has the same effect as ref in C#, in case you know C#.
While the string "**" does have a well defined meaning, I think the answer to the questions is "**" is not one operator, but two "*" in a row.
This is in contrast to Fortran where "**" is a single token and functions as the exponentiation operator.
So the meaning is well covered by Martin Beckett, but it really isn't "an operator".