A char *
is a pointer to a char
(or a sequence of char
s -- aka a string) while a char[]
is an array of char
s. They're both interchangeably used, but here are some main differences.
If you use a
char *
, as a member of a struct, you have to allocate memory for it separately usingmalloc()
while if you used achar[]
, all you need to do is to specify the size of that array. So for example, given these 2 structs,typedef struct s1 { char *str; } s1; // some code s1 *ptr1 = malloc(sizeof(s1)); // allocate memory for an s1 // if we wanna use ptr1->str, we have to allocate memory separately for it ptr1->str = malloc(sizeof(LENGTH)); // allocate memory for str // some code
On the other hand,
typedef struct s2 { char arr[LENGTH]; } s2; // some code s2 *ptr2 = malloc(sizeof(s2)); // allocate memory for an s2 // you can now initialize ptr2->arr directly here without mallocing memory for it
Since you're allocating memory for
char *
variables separately, you also need to free them separately while achar[]
is automatically freed when you callfree()
on a pointer to this specific struct. For example,// free data free(ptr1->str); // we have to free ptr->str first free(ptr1); // then free ptr itself
On the other hand,
// free data free(ptr2); // no need to free ptr2->arr
One last thing is that you won't be able to initialize a
char[]
with a string literal if you've declared it separately as it's the case here. You have to initialize it character by character while achar *
can be initialized with a string literal anytime even if you didn't allocate memory for it and of course you won't need to free it separately in this case since you didn't malloc memory for it at the first place. So for example,ptr1->str = "hello"; // initialize ptr->str
On the other hand,
// initialize ptr2->arr ptr2->arr[0] = 'h'; ptr2->arr[1] = 'e'; ptr2->arr[2] = 'l'; ptr2->arr[3] = 'l'; ptr2->arr[4] = 'o'; ptr2->arr[5] = '\0';
In this situation, word
is a pointer to a char (or a sequence of chars). It contains the address of the block of memory it points to. &word
is the address of that pointer. It returns the address of word
. *word
deferencesdereferences the address that word
contains which gives us the first character in that block (since the address of the first character is the same as the address of the whole block). This [answer][1] has a good visual representation to this.
#include <stdio.h>
// prototypes
unsigned int getLength(char *str);
int main(void)
{
char *str = "hello"; // create a string
unsigned int l = getLenghtgetLength(str); // pass str to a function
printf("Length: %u\n", l); // print the length
}
unsigned int getLength(char *str) // accepts a char *
{
// calculate the length of str
unsigned int length = 0;
// while the current character is not the null terminator
while (str[length] != '\0')
{
length++; // increase the length by 1
}
return length;
}