Two asterisks before variable name - c

While digging in some C source code I found that fragment of code
char **words
I know that single asterisk before variable name "points" to pointer, but what is the purpose of those two asterisks ?

It is a pointer to a pointer.
It is used primarily when you use an array of character strings.
For example: you have char sample[5][5]; - this can store 5 strings of length 4;
If you need to pass it to a function, func(sample);
And the function definition of such a function would be func(char **temp);

// your imagination is the limit
char letter;
char *word; // sequence of letters
char **sentence; // sequence of words
char ***paragraph; // sequence of sentences
char ****book; // sequence of paragraphs
char *****library; // sequence of books
The data structure is probably not the best to represent the concept: this is just an illustration.

simple dude!
it points to the pointer thats it
**a points to the pointer *a
thats it.
For more information you can google it

Related

char *filenames[1] or char *filenames What is the difference?

I am writing a program which will store a list of file names as a string array. When I declare it as
char *filenames[1]
I have no errors... but when I do
char *filenames
I get a few errors. Not at the declaration but in later use. for example when I do:
filenames[3]= (char*)malloc( strlen(line) + 1);//here ERROR is : Cannot assign char* to char.
But with the first declaration with [1] it is all fine. I was just wondering what is the difference between them?
Trust me I tried looking for the answer on google but can't find any good ones regarding this case.
At the outset, char *filenames represents a char * variable named filenames whereas, char *filenames[1] represents an array of char * variables, with one element.
From the point of the usage, both are same, but the major difference is, the first one has to be used as a normal variable and the second one can be indexed, as an array.
If you're in need to use only one variable, don't use an array. You may be in danger of using out of bound indexes if you're not careful enough.
Also, as a note, please see this discussion on why not to cast the return value of malloc() and family in C..
Relative to this statement
filenames[3]= (char*)malloc( strlen(line) + 1);//here ERROR is : Cannot assign char* to char.
the both declarations are wrong.
The firwt declaration
char *filenames[1]
is wrong because it declares an array of pointers to char having only one element. But in the statement with memory allocation there is used index 3. So there is an attempt to access memory beyond the array becuase the only valid index for an array that has one element is 0.
The second declaration
char *filenames
is wrong because it does not declare an array of pointers. So applying the subscript operator for identifier filenames
filenames[3]
gives a scalar object of type char instead of a pointer of type char *

Convert struct field to unsigned char string

I'm on an embedded system so do not have access to a most of the standard library. I have a struct which contains char values.
I have a simple print function which simply outputs an unsigned char string to an attached screen. It does not support format specifiers like printf does.
This is the struct:
typedef struct my_options{
char test;
} my_options;
And this is where I'm trying to output the value:
struct my_options options;
print(options.test); //Here I get "implicit conversion of int to ptr"
How do I achieve this?
Create a char array to hold your char and then print it:
char wrapper[2];
wrapper[0] = options.test;
wrapper[1] = '\0';
print(wrapper);
Create a temporary 2-character long string that has the character to print, and then the terminator. Then pass that string to your print() function:
void print_options(const struct my_options *opt)
{
char tmp[] = { opt->test, '\0' };
print(tmp);
}
your member test if of the type char, where the print function expects an argument of the type const char * (assuming the const bit here, but that's what I'd expect, this as an asside). Passing the address of test then would seem like the appropriate solution, but is it?
No, of course it isn't. There is no absolute guarantee that the next byte after test will be '\0' (a string terminating char). What you, then, ought to do is create a wrapper string:
char char_wrapper[2] = {};//initializes according to standard
//but as Lundin pointed out, self-documenting code is important:
char_wrapper[0] = options.test;?
char_wrapper[1] = '\0';//explicit, so it's clear what this code does
print(char_wrapper);
That should work just fine.
You can, of course, write this as a one-liner:
char char_wrapper[2] = {options.test, '\0'};//same as before, only in 1 statement
print(char_wrapper);//print "string"
That should do it, really. You don't even have to explicitly write the terminating char, since the standard specifically states:
An array of character type may be initialized by a character string literal, optionally
enclosed in braces. Successive characters of the character string literal (including the
terminating null character if there is room or if the array is of unknown size) initialize the
elements of the array.
6.7.8 Initialization cf p. 138, semantics, point 14
Be that as it may, I'd still prefer to browse the web, or just set about writing your own minor implementation of printf so you can use format specifiers. Heck, it's one of the first exercises in the K&R book, and there's tons of solutions floating about on the net. check those out, and adapt them to your specific needs.
Or, perhaps define print to accept a size_t argument, to specify how many chars you want to pass to the output stream. and call it like so print(options.test, 1);
print is looking for a char*. You are passing an char which can also be represented as an int. Thus, the function is trying to implicitly convert an int to a pointer as it is telling you.
char ptr[2];
ptr[0] = options.test;
ptr[1] = '\0';
Would wrap the char into a char array, which in C will decay into a pointer when you pass it to a function.

Casting a char * to a char * [] in C

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).

How can this char array store four separate strings?

I'm confused by this snippet from the book I'm reading. Text strings are put into a char array. There are four words, with four elements in the array. Wait, but that means a single char element is containing a whole text string. I'm certain chars can only handle a single character. Here's the code.
const char *words[4] = { "aardvark", "abacus",
"allude", "zygote" };
So what gives? How can the author be using chars to store whole strings? I know the solution must be blindingly obvious, but I just can't see it. Also, what's with the const keyword? Why would it need to be read only if all we plan to do with this array is count the length of each word using strlen()?
The code does not use chars to store strings, note that the declaration is an array of char *.
A char can hold a single character, and a char * can be used to point to the first element of an array of characters, which can hold a standard C string. This is an important C fundamental: see a char * and you should immediately think of null-terminated C strings.
Similarly, an int * can be used to refer to an entire array of int, by holding the address of the first int in the array. int* can be subscripted the same as an array declared using [].
A char * can also be used to simply hold the address of a single character - i.e. not the first character in a null terminated string.
How can the author be using chars to store whole strings?
he can't. You notice the asterisk, right?
The point your missing is the *.
char letter = 'a'; //stores a single character
char *word = "bigger"; //stores a string literal
this means word is really:
word ---> [b][i][g][g][e][r][\0]
pointing to a bunch of chars (or a "string" of chars). In your example the author defined:
const char *words[4] = { "aardvark", "abacus", "allude", "zygote" };
So you have 4 strings of chars, which are constant. The const was the author's choice to add that on there... it could have been left off. It's just a safeguard, a note to the compiler (and author) that these values were not ment to be modified.

C notation: pointer to array of chars (string)

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.

Resources