home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / doc / ctut / ct4 < prev    next >
Encoding:
Text File  |  1975-06-26  |  9.2 KB  |  527 lines

  1. .NH
  2. Pointers
  3. .PP
  4. A
  5. .ul
  6. pointer
  7. in C is the address of something.
  8. It is a rare case indeed when we care what
  9. the specific address itself is,
  10. but pointers are a quite common way to get at
  11. the contents of something.
  12. The unary operator `&' is used to produce the address of
  13. an object, if it has one. Thus
  14. .E1
  15.     int a, b;
  16.     b = &a;
  17. .E2
  18. puts the address of
  19. .UL a
  20. into
  21. .UL b\*.
  22. We can't do much with it except print it or pass it
  23. to some other routine, because we haven't given
  24. .UL b
  25. the right kind of declaration.
  26. But if we declare that
  27. .UL b
  28. is indeed a
  29. .ul
  30. pointer
  31. to an integer, we're in good shape:
  32. .E1
  33.     int a, \**b, c;
  34.     b = &a;
  35.     c = \**b;
  36. .E2
  37. .UL b
  38. contains the address of
  39. .UL a
  40. and
  41. .UL `c 
  42. .UL =
  43. .UL \**b'
  44. means to use the value in
  45. .UL b
  46. as an address, i.e., as a pointer.
  47. The effect is that we get back the contents of 
  48. .UL a,
  49. albeit rather indirectly.
  50. (It's always the case that 
  51. .UL `\**&x'
  52. is the same as
  53. .UL x
  54. if
  55. .UL x
  56. has an address.)
  57. .PP
  58. The most frequent use of pointers in C is for walking
  59. efficiently along arrays.
  60. In fact,
  61. in the implementation of an array,
  62. the array name
  63. represents the address of the zeroth element of the array,
  64. so you can't use it on the left side of an expression.
  65. (You can't change the address of something by assigning to it.)
  66. If we say
  67. .E1
  68. char \**y;
  69. char x[100];
  70. .E2
  71. .UL y
  72. is of type pointer to character
  73. (although it doesn't yet point anywhere).
  74. We can make 
  75. .UL y
  76. point to
  77. an element of
  78. .UL x
  79. by either of
  80. .E1
  81. y = &x[0];
  82. y = x;
  83. .E2
  84. Since 
  85. .UL x
  86. is the address of
  87. .UL x[0]
  88. this is legal and consistent.
  89. .PP
  90. Now 
  91. .UL `\**y'
  92. gives
  93. .UL x[0]\*.
  94. More importantly,
  95. .E1
  96. \**(y+1)    gives x[1]
  97. \**(y+i)    gives x[i]
  98. .E2
  99. and the sequence
  100. .E1
  101.     y = &x[0];
  102.     y\*+;
  103. .E2
  104. leaves 
  105. .UL y
  106. pointing at
  107. .UL x[1]\*.
  108. .PP
  109. Let's use pointers
  110. in a function
  111. .UL length
  112. that computes how long a character array is.
  113. Remember that by convention all character arrays are
  114. terminated with a `\\0'.
  115. (And if they aren't, this program will blow up inevitably.)
  116. The old way:
  117. .E1
  118. length(s)
  119.    char s[ ]; {
  120.     int n;
  121.     for( n=0; s[n] != '\\0'; )
  122.         n\*+;
  123.     return(n);
  124. }
  125. .E2
  126. Rewriting with pointers gives
  127. .E1
  128. length(s)
  129.    char \**s; {
  130.     int n;
  131.     for( n=0; \**s != '\\0'; s\*+ )
  132.         n\*+;
  133.     return(n);
  134. }
  135. .E2
  136. You can now see why we have to say what kind of thing
  137. .UL s
  138. points to _
  139. if we're to increment it with
  140. .UL s\*+
  141. we have to increment it by the right amount.
  142. .PP
  143. The pointer version is more efficient
  144. (this is almost always true)
  145. but even more compact is
  146. .E1
  147.     for( n=0; \**s\*+ != '\\0'; n\*+ );
  148. .E2
  149. The 
  150. .UL `\**s'
  151. returns a character;
  152. the
  153. .UL `\*+'
  154. increments the pointer so we'll get the next character
  155. next time around.
  156. As you can see, as we make things more efficient,
  157. we also make them less clear.
  158. But
  159. .UL `\**s\*+'
  160. is an idiom so common
  161. that you have to know it.
  162. .PP
  163. Going a step further,
  164. here's our function
  165. .UL strcopy
  166. that copies a character array
  167. .UL s
  168. to another
  169. .UL t\*.
  170. .E1
  171. strcopy(s,t)
  172.    char \**s, \**t; {
  173.     while(\**t\*+ = \**s\*+);
  174. }
  175. .E2
  176. We have omitted the test against `\\0',
  177. because `\\0' is identically zero;
  178. you will often see the code this way.
  179. (You 
  180. .ul
  181. must
  182. have a space after the `=':
  183. see section 25.)
  184. .PP
  185. For arguments
  186. to a function, and there only,
  187. the declarations
  188. .E1
  189. char s[ ];
  190. char \**s;
  191. .E2
  192. are equivalent _ a pointer to a type,
  193. or an array of unspecified size of that type, are the same thing.
  194. .PP
  195. If this all seems mysterious, copy these forms until they become second nature.
  196. You don't often need anything more complicated.
  197. .NH
  198. Function Arguments
  199. .PP
  200. Look back at the function
  201. .UL strcopy
  202. in the previous section.
  203. We passed it two string names as arguments, then proceeded
  204. to clobber both of them by incrementation.
  205. So how come we don't lose the original strings
  206. in the function that called
  207. .UL strcopy?
  208. .PP
  209. As we said before,
  210. C is a ``call by value'' language:
  211. when you make a function call like
  212. .UL f(x),
  213. the
  214. .ul
  215. value
  216. of
  217. .UL x
  218. is passed,
  219. not its address.
  220. So there's no way to 
  221. .ul
  222. alter
  223. .UL x
  224. from inside
  225. .UL f\*.
  226. If
  227. .UL x
  228. is an array
  229. .UL (char 
  230. .UL x[10])
  231. this isn't a problem, because
  232. .UL x
  233. .ul
  234. is
  235. an address anyway,
  236. and you're not trying to change it,
  237. just what it addresses.
  238. This is why
  239. .UL strcopy
  240. works as it does.
  241. And it's convenient not to have to worry about
  242. making temporary copies of the input arguments.
  243. .PP
  244. But what if
  245. .UL x
  246. is a scalar and
  247. you do want to change it?
  248. In that case,
  249. you have to pass the
  250. .ul
  251. address
  252. of
  253. .UL x
  254. to
  255. .UL f,
  256. and then use it as a pointer.
  257. Thus for example, to interchange two integers, we must write
  258. .E1
  259. flip(x, y)
  260.    int \**x, \**y; {
  261.     int temp;
  262.     temp = \**x;
  263.     \**x = \**y;
  264.     \**y = temp;
  265. }
  266. .E2
  267. and to call 
  268. .UL flip,
  269. we have to pass the addresses of the variables:
  270. .E1
  271. flip (&a, &b);
  272. .E2
  273. .NH
  274. Multiple Levels of Pointers; Program Arguments
  275. .PP
  276. When a C program is called,
  277. the arguments on the command line are made available
  278. to the main program as an argument count
  279. .UL argc
  280. and an array of character strings
  281. .UL argv
  282. containing the arguments.
  283. Manipulating these arguments is one of the most common uses of
  284. multiple levels of pointers
  285. (``pointer to pointer to ...'').
  286. By convention,
  287. .UL argc
  288. is greater than zero;
  289. the first argument
  290. (in
  291. .UL argv[0])
  292. is the command name itself.
  293. .PP
  294. Here is a program that simply echoes its arguments.
  295. .E1
  296. main(argc, argv)
  297.    int argc;
  298.    char \**\**argv; {
  299.     int i;
  300.     for( i=1; i < argc; i\*+ )
  301.         printf("%s ", argv[i]);
  302.     putchar('\\n');
  303. }
  304. .E2
  305. Step by step:
  306. .UL main
  307. is called with two arguments,
  308. the argument count and the array of arguments.
  309. .UL argv
  310. is a pointer to an array,
  311. whose individual elements are pointers to arrays of characters.
  312. The zeroth argument is the name of the command itself,
  313. so we start to print 
  314. with the first argument, until we've printed them all.
  315. Each 
  316. .UL argv[i]
  317. is a character array, so we use a
  318. .UL `%s'
  319. in the
  320. .UL printf\*.
  321. .PP
  322. You will sometimes see the declaration of
  323. .UL argv
  324. written as
  325. .E1
  326. char \**argv[ ];
  327. .E2
  328. which is equivalent.
  329. But we can't use 
  330. .UL char 
  331. .UL argv[ 
  332. .UL ][
  333. .UL ],
  334. because both dimensions are variable and
  335. there would be no way to figure
  336. out how big the array is.
  337. .PP
  338. Here's a bigger example using
  339. .UL argc
  340. and
  341. .UL argv\*.
  342. A common convention in C programs is that 
  343. if the first argument is `\(mi',
  344. it indicates a flag of some sort.
  345. For example, suppose we want a program to be callable as
  346. .E1
  347. prog -abc arg1 arg2 \*.\*.\*.
  348. .E2
  349. where the `\(mi' argument is optional;
  350. if it is present, it may be followed by any combination of
  351. a, b, and c.
  352. .E1
  353. main(argc, argv)
  354.    int argc;
  355.    char \**\**argv; {
  356.     \*.\*.\*.
  357.     aflag = bflag = cflag  = 0;
  358.     if( argc > 1 && argv[1][0] \*= '-' ) {
  359.         for( i=1; (c=argv[1][i]) != '\\0'; i\*+ )
  360.             if( c\*='a' )
  361.                 aflag\*+;
  362.             else if( c\*='b' )
  363.                 bflag\*+;
  364.             else if( c\*='c' )
  365.                 cflag\*+;
  366.             else
  367.                 printf("%c?\\n", c);
  368.         --argc;
  369.         \*+argv;
  370.     }
  371.     \*.\*.\*.
  372. .E2
  373. .PP
  374. There are several things worth noticing about this code.
  375. First, there is a real need for the left-to-right evaluation
  376. that && provides;
  377. we don't want to look at
  378. .UL argv[1]
  379. unless we know it's there.
  380. Second, the statements
  381. .E1
  382.     --argc;
  383.     \*+argv;
  384. .E2
  385. let us march along the argument list by one position,
  386. so we can skip over the flag argument as if it had never existed _
  387. the rest of the program is independent of
  388. whether or not there was a flag argument.
  389. This only works because 
  390. .UL argv
  391. is a pointer which can be incremented.
  392. .NH
  393. The Switch Statement; Break; Continue
  394. .PP
  395. The
  396. .UL switch
  397. statement
  398. can be used to replace the multi-way test
  399. we used in the last example.
  400. When the tests are like this:
  401. .E1
  402. if( c \*= 'a' ) \*.\*.\*.
  403. else if( c \*= 'b' ) \*.\*.\*.
  404. else if( c \*= 'c' ) \*.\*.\*.
  405. else \*.\*.\*.
  406. .E2
  407. testing a value against a series of
  408. .ul
  409. constants,
  410. the
  411. switch
  412. statement is often clearer and usually gives better code.
  413. Use it like this:
  414. .E1
  415. switch( c ) {
  416.  
  417. case 'a':
  418.     aflag\*+;
  419.     break;
  420. case 'b':
  421.     bflag\*+;
  422.     break;
  423. case 'c':
  424.     cflag\*+;
  425.     break;
  426. default:
  427.     printf("%c?\\n", c);
  428.     break;
  429. }
  430. .E2
  431. The
  432. .UL case
  433. statements label the various actions we want;
  434. .UL default
  435. gets done if none of the other cases are satisfied.
  436. (A
  437. .UL default
  438. is optional;
  439. if it isn't there,
  440. and none of the cases match,
  441. you just fall out the bottom.)
  442. .PP
  443. The
  444. .UL break
  445. statement in this example is new.
  446. It is there
  447. because
  448. the cases are just labels,
  449. and after you do one of them,
  450. you
  451. .ul
  452. fall through
  453. to the next unless you take some explicit action to escape.
  454. This is a mixed blessing.
  455. On the positive side,
  456. you can have multiple cases on a single statement;
  457. we might want to allow both upper and lower case letters in our flag field,
  458. so we could say
  459. .E1
  460. case 'a':  case 'A':    \*.\*.\*.
  461. .SP
  462. case 'b':  case 'B':    \*.\*.\*.
  463.  etc\*.
  464. .E2
  465. But what if we just want to get out 
  466. after doing
  467. .UL case 
  468. .UL `a'
  469. ?
  470. We could get out of a
  471. .UL case
  472. of the
  473. .UL switch
  474. with a label and a
  475. .UL goto,
  476. but this is really ugly.
  477. The
  478. .UL break
  479. statement lets us exit without either
  480. .UL goto
  481. or label.
  482. .E1
  483. switch( c ) {
  484.  
  485. case 'a':
  486.     aflag\*+;
  487.     break;
  488. case 'b':
  489.     bflag\*+;
  490.     break;
  491.  \*.\*.\*.
  492. }
  493. /\** the break statements get us here directly \**/
  494. .E2
  495. The
  496. .UL break
  497. statement
  498. also works in
  499. .UL for
  500. and
  501. .UL while
  502. statements _
  503. it causes an immediate exit from the loop.
  504. .PP
  505. The
  506. .UL continue
  507. statement works
  508. .ul
  509. only
  510. inside
  511. .UL for's
  512. and
  513. .UL while's;
  514. it causes the next iteration of the loop to be started.
  515. This means it goes to the increment part of the
  516. .UL for
  517. and the test part of the
  518. .UL while\*.
  519. We could have used a
  520. .UL continue
  521. in our example to get on with the next iteration
  522. of the
  523. .UL for,
  524. but it seems clearer to use
  525. .UL break
  526. instead.
  527.