Pointers

advertisement
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)
Download