1 00:00:07,185 --> 00:00:09,540 CHRIS GERBER: A function is a series of steps within a 2 00:00:09,540 --> 00:00:12,000 larger program, which is usually intended to be called 3 00:00:12,000 --> 00:00:14,440 multiple times and from multiple other locations in 4 00:00:14,440 --> 00:00:15,720 the program. 5 00:00:15,720 --> 00:00:18,480 When creating a C function, one of the requirements is to 6 00:00:18,480 --> 00:00:21,050 specify a return value type. 7 00:00:21,050 --> 00:00:23,490 The simplest case is a situation where the calling 8 00:00:23,490 --> 00:00:26,510 code is not concerned with the result of the function. 9 00:00:26,510 --> 00:00:28,530 This might be the case when we are printing data to the 10 00:00:28,530 --> 00:00:31,120 user's display, as with printf. 11 00:00:31,120 --> 00:00:33,140 In this case, we can declare a return value 12 00:00:33,140 --> 00:00:35,020 to be of type void. 13 00:00:35,020 --> 00:00:37,130 Using void simply tells the compiler that no 14 00:00:37,130 --> 00:00:39,120 value will be returned. 15 00:00:39,120 --> 00:00:40,530 Let's see what this looks like. 16 00:00:40,530 --> 00:00:42,940 >> Let's say that we have a function called say_hello that 17 00:00:42,940 --> 00:00:44,490 takes one argument. 18 00:00:44,490 --> 00:00:47,050 We'll pass it a person's name and it will display a greeting 19 00:00:47,050 --> 00:00:48,380 on the screen. 20 00:00:48,380 --> 00:00:50,505 The name will be of type char*. 21 00:00:50,505 --> 00:00:53,080 And we'll specify that as the argument. 22 00:00:53,080 --> 00:00:55,970 My application doesn't need to know what was printed or if it 23 00:00:55,970 --> 00:00:56,970 was printed. 24 00:00:56,970 --> 00:00:59,680 So the return value will be of type void. 25 00:00:59,680 --> 00:01:02,060 This function may print to the screen with a command like 26 00:01:02,060 --> 00:01:07,620 printf("Hello, %s\n 27 00:01:07,620 --> 00:01:12,100 ", name);. 28 00:01:12,100 --> 00:01:14,690 The greeting will be displayed and control will be passed 29 00:01:14,690 --> 00:01:16,260 back to the calling code. 30 00:01:16,260 --> 00:01:19,370 One thing to note is that when the return value type is void, 31 00:01:19,370 --> 00:01:20,790 you do not need to include a return 32 00:01:20,790 --> 00:01:22,300 statement in the function. 33 00:01:22,300 --> 00:01:25,270 If you choose to include one, don't include a return value 34 00:01:25,270 --> 00:01:27,420 as an argument. 35 00:01:27,420 --> 00:01:29,380 >> In some cases, it makes sense to return a 36 00:01:29,380 --> 00:01:30,570 value from a function. 37 00:01:30,570 --> 00:01:33,900 Let's say that we were writing a function called add_floats. 38 00:01:33,900 --> 00:01:36,160 We'll pass it two arguments, both floats, 39 00:01:36,160 --> 00:01:37,510 called first and second. 40 00:01:37,510 --> 00:01:40,520 And it will tell us what the sum of those floats is. 41 00:01:40,520 --> 00:01:43,000 We know that if we add two floats together, the result 42 00:01:43,000 --> 00:01:44,120 will be a float. 43 00:01:44,120 --> 00:01:47,540 Given that, we choose a return type of float. 44 00:01:47,540 --> 00:01:50,040 This function will perform this calculation and return 45 00:01:50,040 --> 00:01:52,260 the values in a statement like return 46 00:01:52,260 --> 00:01:54,770 first + second;. 47 00:01:54,770 --> 00:01:57,300 When control is passed back to the calling code, the 48 00:01:57,300 --> 00:02:00,030 resulting value is now available to that code. 49 00:02:00,030 --> 00:02:04,250 We can store this value like so: float result = 50 00:02:04,250 --> 00:02:09,410 add_floats(3.14, 1.62 51 00:02:09,410 --> 00:02:11,290 );. 52 00:02:11,290 --> 00:02:15,200 Result in this case would now contain the value 4.76. 53 00:02:15,200 --> 00:02:18,620 >> As a reminder, floating point values are imprecise. 54 00:02:18,620 --> 00:02:21,250 So if this was a financial calculation, using dollars and 55 00:02:21,250 --> 00:02:24,960 cents, we may want to consider a precise data type such as 56 00:02:24,960 --> 00:02:29,120 int and perform the calculation in pennies. 57 00:02:29,120 --> 00:02:31,270 >> Another case where we would want to return a value from a 58 00:02:31,270 --> 00:02:33,980 function is when we want to know if a function was 59 00:02:33,980 --> 00:02:35,960 successful. 60 00:02:35,960 --> 00:02:39,190 If it was not successful, we may also want to know what type of 61 00:02:39,190 --> 00:02:41,250 error occurred. 62 00:02:41,250 --> 00:02:43,647 Let's say that we're trying to open a file on disk to count 63 00:02:43,647 --> 00:02:45,220 the number of characters in it. 64 00:02:45,220 --> 00:02:48,635 If the file can't be opened, we want to be able to stop and 65 00:02:48,635 --> 00:02:50,910 tell the user about the problem. 66 00:02:50,910 --> 00:02:54,070 >> We'll call our function count_file_chars and it will 67 00:02:54,070 --> 00:02:55,490 take one argument. 68 00:02:55,490 --> 00:02:57,420 We'll pass in the name of the file using a 69 00:02:57,420 --> 00:02:59,610 char* called filename. 70 00:02:59,610 --> 00:03:03,050 This function might look something like this. 71 00:03:03,050 --> 00:03:05,450 In this example, we would expect the count returned to 72 00:03:05,450 --> 00:03:07,130 be 0 or more. 73 00:03:07,130 --> 00:03:08,870 This leaves us the negative integers to 74 00:03:08,870 --> 00:03:10,200 use as sentinel values. 75 00:03:10,200 --> 00:03:13,320 A sentinel value is simply a special value that is not 76 00:03:13,320 --> 00:03:16,200 legitimate data but does convey information. 77 00:03:16,200 --> 00:03:19,480 Here, if I return a -1 to the calling code, I am 78 00:03:19,480 --> 00:03:21,830 actually sending the message that an error occurred while 79 00:03:21,830 --> 00:03:23,810 trying to access the file. 80 00:03:23,810 --> 00:03:26,060 I could then check that return value to determine if my 81 00:03:26,060 --> 00:03:28,060 function call was successful. 82 00:03:28,060 --> 00:03:30,350 If the number was 0 or greater, I would know the 83 00:03:30,350 --> 00:03:32,180 number of characters in the file. 84 00:03:32,180 --> 00:03:35,310 If, however, the number was less than 0, I could simply 85 00:03:35,310 --> 00:03:37,350 print that a problem had occurred. 86 00:03:37,350 --> 00:03:40,120 One trade-off to consider is that by reserving all the 87 00:03:40,120 --> 00:03:43,180 negative values as sentinel values, assuming this is a 88 00:03:43,180 --> 00:03:46,070 32-bit integer, I have essentially taken away around 89 00:03:46,070 --> 00:03:48,970 2 billion possible return values. 90 00:03:48,970 --> 00:03:51,270 >> Return value types are one of the most important elements of 91 00:03:51,270 --> 00:03:52,460 function calls. 92 00:03:52,460 --> 00:03:54,670 Hopefully this short overview has helped you think about 93 00:03:54,670 --> 00:03:59,110 three key types: void, result values, and sentinel values, 94 00:03:59,110 --> 00:04:00,190 and when each of the three might be 95 00:04:00,190 --> 00:04:02,010 appropriate in your code. 96 00:04:02,010 --> 00:04:03,260 Thanks for watching.