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.
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 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;
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).
This is a general question about C.(I dont have a lot of experience coding in C)
So, if I have a function that takes a char* as an argument. How to know whether its a pointer to a single char or a char array, because if it's a char array I can expect a \0 but if it's not a char array then I wouldn't want to search for \0.
Is char* in argument a pointer to a single char or a char array?
Yes.
A parameter of type char* is always a pointer to a char object (or a null pointer, not pointing to anything, if that's what the caller passes as the corresponding argument).
It's not a pointer to an array (that would be, for example, a pointer of type char(*)[42]), but the usual way to access the elements of an array is via a pointer to the element type, not to the whole array. Why? Because an actual pointer-to-array must always specify the length of the array (42 in my example), which is inflexible and doesn't let the same function deal with arrays of different lengths.
A char* parameter can be treated just as a pointer to a single char object. For example, a function that gets a character of input might be declared like this:
bool get_next_char(char *c);
The idea here is that the function's result tells you whether it was successful; the actual input character is "returned" via the pointer. (This is a contrived example; <stdio.h> already has several functions that read characters from input, and they don't use this mechanism.)
Compare the strlen function, which computes the length of a string:
size_t strlen(const char *s);
s points to the first element of an array of char; internally, strlen uses that pointer to traverse the array, looking for the terminating '\0' character.
Ignoring the const, there's no real difference between the char* parameters for these two functions. In fact, C has no good way to distinguish between these cases: a pointer that simply points to a single object vs. a pointer that points to the first element of an array.
It does have a bad way to make that distinction. For example, strlen could be declared as:
size_t strlen(const char s[]);
But C doesn't really have parameters of array type at all. The parameter declaration const char s[] is "adjusted" to const char *s; it means exactly the same thing. You can even declare a length for something that looks like an array parameter:
void foo(char s[42]);
and it will be quietly ignored; the above really means exactly the same thing as:
void foo(char *s);
The [42] may have some documentation value, but a comment has the same value -- and the same significance as far as the compiler is concerned.
Any distinction between a pointer to a single object and a pointer to the first element of an array has to be made by the programmer, preferably in the documentation for the function.
Furthermore, this mechanism doesn't let the function know how long the array is. For char* pointers in particular, it's common to use the null character '\0' as a marker for the end of a string -- which means it's the callers responsibility to ensure that that marker is actually there. Otherwise, you can pass the length as a separate argument, probably of type size_t. Or you can use any other mechanism you like, as long as everything is done consistently.
... because if it's a char array I can expect a \0 ...
No, you can't, at least not necessarily. A char* could easily point to the first element of a char array that's not terminated by a '\0' character (i.e., that doesn't contain a string). You can impose such a requirement if you like. The standard library functions that operate on strings impose that requirement -- but they don't enforce it. For example, if you pass a pointer to an unterminated array to strlen, the behavior is undefined.
Recommended reading: Section 6 of the comp.lang.c FAQ.
You cannot determine how many bytes are referenced by a pointer. You need to keep track of this yourself.
It is possible that a char array is NOT terminated with a \0 in which case you need to know the length of the array. Also, it is possible for an array to have a length of 1, in which case you have one character with no terminating \0.
The nice thing about C is that you get to define the details about data structures, thus you are NOT limited to a char array always ending with \0.
Some of the terms used to describe C data structures are synonymous. For example, an array is sequential series of data elements, an array of characters is a string, and a string can be terminated with a null char (\0).
I have seen in several pieces of code a string declared as char*. How does this work, surely it is a pointer to a single char, not an array of chars which makes up a string. If I wished to take string input to a method that would be called like this:
theMethod("This is a string literal");
What datatype should the parameter be?
surely it is a pointer to a single char, not an array of chars
It's a pointer to the first character of an array of char. One can access each element of the array using a pointer to its first element by performing pointer arithmetic and "array" indexing.
What datatype should the parameter be?
const char *, if you don't wish to modify the characters from within the function (this is the general case), and char * if you do.
This is a common beginner-C confusion. A pointer to any type, T *, is ambiguously either a pointer to a single object of type T, or a pointer to an element within a linear array of objects of type T, size unspecified. You, the programmer, are responsible for knowing which is which, and passing around length information as necessary. If you get it wrong, the compiler stands by and watches as your program drives off the undefined-behavior cliff.
To the extent C has strings (there is a strong case to be made that it doesn't really) they take shameless advantage of this ambiguity, such that when you see char * or const char * in a C program, it almost always will be a pointer to a string, not a single char. The same is not true of pointers to any other type.
per definition is "string" of type char * (or unsigned char * or const char *) however, it is a pointer to the first character of that character chain (i dont want to use the words array or vector). The Difference is to see in char: 'x' (single quote)
this is good old c programming (sometimes i could cry for loosing it)
char *p = "i am here";
for (q=p; ++q; *q) { // so lets start with p walk through and end wit the /0 after the last e
if (*q=='h') { // lets find the first 'h' and cut the string there
*(q-1)=0;
break;
}
}
i used no const and other probs here, i just try to clearify