Pointers Pointers are important within many programming languages. PL/I, C, and C++ give the programmer explicit use of pointers; whereas, Java hides the usage. Pointers contain addresses which point to something. In C, pointers are used implicitly when passing arrays as parameters. In C, pointers are used explicitly when needing to return a value in a numeric variable or other primitive types. The invoking parameter will use an & reference operator to explicitly state that we are passing the address. The function's parameter will use an '*' to indicate the pointer. To set/access the value of the function's parameter, use the '*' dereference operator. In C, pointers are used explictly when passing a structure either to improve performance or to set an attribute's value. The invoking parameter will use an '&' reference operator. The function's parameter will use an '*' to indicate a pointer. References to attributes in the structure will use '->'. Also, if you need to copy the structure, use the '*' dereference operator. In C, pointers are used explicitly when dynamically allocating memory. This is frequently done for variable-sized data. Allocation of dynamic memory uses the malloc function which returns a pointer to the allocated memory. void *malloc(int iSizeInBytes) // This example passes addresses implicitly for // the exam array, and explicitly for returning // numeric values double dExamM[100]; double dExamMin; double dExamMax; … determineMinMax(dExamM, iExamCnt, &dExamMin, &dExamMax) … void determineMinMax(double dExamM[], int iExamCnt , double *pdExamMin, double *pdExamMax) { int i; *pdExamMax = 0; if (iExamCnt == 0) { *dExamMin = 0; return; } *pdExamMin = 200; // arbitrary high value for (i = 0; i < iExamCnt; i++) { if (dExamM[i] < *pdExamMin) *pdExamMin = dExamM[i]; if (dExamM[i] > *pdExamMax) *pdExamMax = dExamM[i]; } } increaseHourlyRate (&employee, dIncreaseAmt); … void increaseHourlyRate(Employee *pEmployee , double dIncreaseRate) { Employee employeeRec; pEmployee->dHourlyRate = pEmployee->dHourlyRate * (1.0 + dIncreaseRate); // ... employeeRec = *pEmployee; // structure assignment } char *pszSentence; int iSentenceLength; char szParagraph[] = "This is a sentence. This is another sentence."; iSentenceLength = strcspn(szParagraph, "."); Dynamically allocated memory has to be deallocated using the free function. free (void *pPointer) We will discuss dynamic memory again when we cover linked lists and trees. Warning Improperly freeing dynamic memory can lead to significant problems: - Memory leaks occur if dynamic memory isn't freed - A freed item that is still being referenced by a pointer is known as a dangling reference. If that pointer is subsequently used, unpredicatable results occur. Pointer Arithmetic C provides pointer arithmetic which is different from integer arithmetic. The unit measure in pointer arithmetic depends on the datatype defined for the pointer. The sizeof that datatype determines the size. When the ++ operator is used with a pointer, the increment isn't necessarily by 1. It increments by the unit measure. Iteration using pointer increments are slightly faster than iteration with subscripts. Why is that? pszSentence = malloc(iSentenceLength+1); strncpy(pszSentence, szParagraph, iSentenceLength); *(pszSentence + iSentenceLength) = '\0'; printf("pszSentence is %p\n", pszSentence); printf("char at that address is %c\n", *pszSentence); printf("char just before sentence length is %c\n" , *(pszSentence + iSentenceLength - 1)); printf("pointer is %p, value is %s\n", pszSentence, pszSentence); free(pszSentence); Output: pszSentence is 00C87818 char at that address is T char just before sentence length is e pointer is 00C87818, value is This is a sentence Memory leaks are very important to a long-running process. it to fail. They can ca The use of a dangling reference can have unpredictable results since th memory may have been already allocated again. char *pcMyChar; // unit measure is 1 byte long *plMyLong; // unit measure is 4 bytes double *pdMyScore; // unit measure is 8 bytes Employee *pemployee; // unit measure is sizeof(Employee) pcMyChar++; // increments by 1 plMyLong++; // increments by 4 pdMyScore++; // increments by 8 pemployee++; // increments by sizeof(Employee) char szName[] = "Bob Wire"; char *pcChar; for (pcChar = &szName[0]; *pcChar != '\0'; pcChar++) { if (*pcChar == ' ') … } // instead of for (i = 0; szName[i] != '\0'; i++) { if (szName[i] == ' ') … } Incrementing by an integer, n, actually adds n* unitMeasure pcMyChar += 3; plMyLong += 3; pdMyScore += 3; pemployee += 3; // // // // increments increments increments increments by by by by 3*1 3*4 3*8 3*sizeof(Employee)