* remove "\r" nonsense
[mascara-docs.git] / C / the.ansi.c.programming.language / c.programming.notes / sx10d.html
blobfdf83976f1236e88fde9df75934f3a5106366b3e
1 <!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
2 <!-- This collection of hypertext pages is Copyright 1995, 1996 by Steve Summit. -->
3 <!-- This material may be freely redistributed and used -->
4 <!-- but may not be republished or sold without permission. -->
5 <html>
6 <head>
7 <link rev="owner" href="mailto:scs@eskimo.com">
8 <link rev="made" href="mailto:scs@eskimo.com">
9 <title>10.4 Null Pointers</title>
10 <link href="sx10c.html" rev=precedes>
11 <link href="sx10e.html" rel=precedes>
12 <link href="sx10.html" rev=subdocument>
13 </head>
14 <body>
15 <H2>10.4 Null Pointers</H2>
17 <p>We said that the value of a pointer variable
18 is a pointer to some other variable.
19 There is one other value a pointer may have:
20 it may be set to a <dfn>null pointer</dfn>.
21 A <dfn>null pointer</dfn> is
22 a special pointer value that is known not to point anywhere.
23 What this means that no other valid pointer,
24 to any other variable or array cell or anything else,
25 will ever compare equal to a null pointer.
26 </p><p>The most straightforward way
28 to ``get'' a null pointer in your program
29 is by using the predefined constant <TT>NULL</TT>,
30 which is defined for you by several standard header files,
31 including <TT>&lt;stdio.h&gt;</TT>, <TT>&lt;stdlib.h&gt;</TT>,
32 and <TT>&lt;string.h&gt;</TT>.
33 To initialize a pointer to a null pointer,
34 you might use code like
35 <pre>
36 #include &lt;stdio.h&gt;
38 int *ip = NULL;
39 </pre>
40 and to test it for a null pointer
41 before inspecting the value pointed to
42 you might use code like
43 <pre>
44 if(ip != NULL)
45 printf("%d\n", *ip);
46 </pre>
47 </p><p>
48 It is also possible to refer to the null pointer
49 by using a constant <TT>0</TT>,
50 and you will see some code that sets null pointers
51 by simply doing
52 <pre>
53 int *ip = 0;
54 </pre>
55 (In fact, <TT>NULL</TT> is a preprocessor macro
56 which typically has the value,
57 or replacement text,
58 <TT>0</TT>.)
59 </p><p>Furthermore,
60 since the definition of ``true'' in C
61 is a value that is not equal to 0,
62 you will see code that tests for non-null pointers
63 with abbreviated code like
64 <pre>
65 if(ip)
66 printf("%d\n", *ip);
67 </pre>
68 This has the same meaning as our previous example;
69 <TT>if(ip)</TT> is equivalent to
70 <TT>if(ip != 0)</TT>
71 and to
72 <TT>if(ip != NULL)</TT>.
73 </p><p>All of these uses are legal,
74 and although I recommend that you use the constant <TT>NULL</TT> for clarity,
75 you will come across the other forms,
76 so you should be able to recognize them.
77 </p><p>You can use a null pointer as a placeholder
78 to remind yourself
79 (or, more importantly, to help your program remember)
80 that a pointer variable does not point anywhere at the moment
81 and that you should not use the ``contents of'' operator on it
82 (that is, you should not try to inspect what it points to,
83 since it doesn't point to anything).
84 A function that returns pointer values
85 can return a null pointer when it is unable to perform its task.
86 (A null pointer used in this way
87 is analogous to the <TT>EOF</TT> value
88 that functions like <TT>getchar</TT> return.)
89 </p><p>As an example, let us write our own version
90 of the standard library function <TT>strstr</TT>,
91 which looks for one string within another,
92 returning a pointer to the string if it can,
93 or a null pointer if it cannot.
94 Here is the function, using the obvious brute-force algorithm:
95 at every character of the input string,
96 the code checks for
97 a match there of the pattern string:
98 <pre>
99 #include &lt;stddef.h&gt;
101 char *mystrstr(char input[], char pat[])
103 char *start, *p1, *p2;
104 for(start = &amp;input[0]; *start != '\0'; start++)
105 { /* for each position in input string... */
106 p1 = pat; /* prepare to check for pattern string there */
107 p2 = start;
108 while(*p1 != '\0')
110 if(*p1 != *p2) /* characters differ */
111 break;
112 p1++;
113 p2++;
115 if(*p1 == '\0') /* found match */
116 return start;
119 return NULL;
121 </pre>
122 The <TT>start</TT> pointer steps over
123 each character position in the <TT>input</TT> string.
124 At each character,
125 the inner loop checks for a match there,
126 by using <TT>p1</TT> to step over the pattern string
127 (<TT>pat</TT>),
128 and <TT>p2</TT> to step over the input string
129 (starting at <TT>start</TT>).
130 We compare successive characters until either
131 (a) we reach the end of the pattern string
132 (<TT>*p1 == '\0'</TT>),
135 we find two characters which differ.
136 When we're done with the inner loop,
137 if we reached the end of the pattern string
138 (<TT>*p1 == '\0'</TT>),
139 it means that all preceding characters matched,
140 and we found a complete match for the pattern starting at <TT>start</TT>,
141 so we return <TT>start</TT>.
142 Otherwise, we go around the outer loop again,
143 to try another starting position.
144 If we run out of those
145 (if <TT>*start == '\0'</TT>),
146 without finding a match,
147 we return a null pointer.
148 </p><p>Notice that the function is declared as returning
149 (and does in fact return)
150 a pointer-to-<TT>char</TT>.
151 </p><p>We can use <TT>mystrstr</TT>
152 (or its standard library counterpart <TT>strstr</TT>)
153 to determine whether one string contains another:
154 <pre>
155 if(mystrstr("Hello, world!", "lo") == NULL)
156 printf("no\n");
157 else printf("yes\n");
158 </pre>
159 </p><p>In general,
160 C does not initialize pointers to null for you,
161 and it never tests pointers to see if they are null before using them.
162 If one of the pointers in your programs
163 points somewhere some of the time but not all of the time,
164 an excellent convention to use
165 is to set it to a null pointer when it doesn't point anywhere valid,
166 and to test to see if it's a null pointer before using it.
167 But you must use explicit code to set it to <TT>NULL</TT>,
168 and to test it against <TT>NULL</TT>.
170 (In other words,
171 just setting an unused pointer variable to <TT>NULL</TT>
172 doesn't guarantee safety;
173 you also have to check for
174 the null value before using the pointer.)
176 On the other hand,
177 if you know that a particular pointer variable is always valid,
178 you don't have
179 to insert
180 a paranoid test against <TT>NULL</TT> before using it.
181 </p><hr>
183 Read sequentially:
184 <a href="sx10c.html" rev=precedes>prev</a>
185 <a href="sx10e.html" rel=precedes>next</a>
186 <a href="sx10.html" rev=subdocument>up</a>
187 <a href="top.html">top</a>
188 </p>
190 This page by <a href="http://www.eskimo.com/~scs/">Steve Summit</a>
191 // <a href="copyright.html">Copyright</a> 1995, 1996
192 // <a href="mailto:scs@eskimo.com">mail feedback</a>
193 </p>
194 </body>
195 </html>