Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Pointers revisited

Tags:

c

pointers

I learning to use Pointers.
I have a few questions about an exercise code I wrote.

First, if I have the following function code:

//function prototype
void processCars(char *, char []);

int main(){
...
//actual callto the function
processCars(strModel[x], answer);
...
}

void processCars(char * string1, char string2[])
{
...
}

How would it be correct the define the arguments of this processCars function? The first one - char * - is a pointer to char, which is the start location of the string (or better an array of chars) ? The second is actually an array of chars directly.

Now, supposed I want to pass by reference a few array of strings and even array of structs. I managed to create the following code which works, but I still don't fully get what I'm doing.

typedef struct car {

    char make[10];
    char model[10];
    int year;
    int miles;

} aCar; // end type

// function prototype
void processCars( aCar * , char **, char **, int *, int *);

//aCar * - a pointer to struct of type car 
//char **, char ** 
// int * - a pointer to integer
//  Arrays passed as arguments are passed by reference.
// so this prototype works to
//void processCars( aCar * , char **, char **, int [], int []);


int main(){

    aCar myCars[3]; // an array of 3 cars

    char *strMakes[3]={"VW","Porsche","Audi"}; // array of 3 pointers?
    char *strModel[3]={"Golf GTI","Carrera","TT"};
    int intYears[3]={2009,2008,2010};
    int intMilage[3]={8889,24367,5982};

    // processCars(myCars, strMakes);
    processCars(myCars, strMakes, strModel, intYears, intMilage);

return 0;
} // end main

//  char ** strMakes is a pointer to array of pointers ?
void processCars( aCar * myCars, char ** strMakes, \
                  char ** strModel, int * intYears, \
                  int * intMilage ){
}

So, my qeustion is how to define this "char ** strMakes". What is it, why is it working for me?

I have also noticed, I can't change part of the string, because if I correct (or the references I read) strings are read only. So, like in python, I can use array indices to access the letter V:

printf("\n%c",strMakes[0][0]); 

But, unlike in python, I can't change it:

strMakes[0][0]="G" // will not work? or is there a way I could not think of?

So, thanks for reading through my long post and many question about pointers and c strings. Your answers are appreciated.

like image 881
oz123 Avatar asked Nov 25 '11 12:11

oz123


1 Answers

Within the function itself, both arguments will be pointers. The [] in the parameter list makes absolutely no difference, it's just syntactic sugar.

Although there is a distinct difference between an array and a pointer, a passed array to a function always decays to a pointer of the corresponding type. For example, an array of type char[3] would decay to char *, char *[3] would decay to char **.

char *strMakes[3] is an array of length 3 that holds pointers to strings stored somewhere else, probably in a read-only area of the process. An attempt to modify the strings themselves will result in undefined behaviour, most probably a protection fault.

If you want to be able to modify the strings, you could declare it as an array holding arrays, not pointers:

char strMakes[3][20] = {"VW", "Porsche", "Audi"};

This way the strings will be stored consecutively within the bounds of the outer array.

Another way is to still have an array of pointers, but the pointers should point to mutable memory:

/* these strings are mutable as long as you don't write past their end */
char str1[] = "VW";
char str2[] = "Porsche";
char str3[] = "Audi";
char *strMakes[3] = {str1, str2, str3};
like image 118
Blagovest Buyukliev Avatar answered Oct 23 '22 05:10

Blagovest Buyukliev