Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:05,360 --> 00:00:06,360
Hello, and welcome.
2
00:00:06,360 --> 00:00:10,360
Welcome to a new section. This section is all about type qualifiers.
3
00:00:10,360 --> 00:00:14,860
The first type of qualifier we're going to discuss in detail is the const type qualifier.
4
00:00:14,860 --> 00:00:18,360
So type qualifiers are basically can be used in front of variables
5
00:00:18,360 --> 00:00:21,910
to give the compiler more information about the intended use of the variable.
6
00:00:22,410 --> 00:00:27,210
It helps with optimization. It's similar to the concept that we previously discussed,
7
00:00:28,110 --> 00:00:31,710
which is storage classes but a little bit different because this has to do more with
8
00:00:31,710 --> 00:00:35,810
optimization. So we're going to discuss a few of the type qualifiers important in c.
9
00:00:36,690 --> 00:00:41,350
Both type qualifiers are const, which we'll do in this lecture and then volatile and restrict.
10
00:00:42,850 --> 00:00:48,450
C90 added two new type qualifiers. Constancy and volatility.
11
00:00:48,950 --> 00:00:51,950
So that's volatile and the constant keywords.
12
00:00:51,950 --> 00:00:55,150
So C90, again, we don't talk about that standard a lot
13
00:00:55,150 --> 00:00:57,450
because there's not much that went on in there.
14
00:00:57,450 --> 00:01:00,810
But for this case, it did add two nice things.
15
00:01:00,810 --> 00:01:04,170
So these properties are declared with the keywords const and volatile,
16
00:01:04,670 --> 00:01:08,660
which create qualified types and that's again what this section is all about.
17
00:01:08,660 --> 00:01:13,100
C99 added a third qualifier which is the restrict qualifier.
18
00:01:13,100 --> 00:01:17,100
This is designated to facilitate compiler optimizations.
19
00:01:18,330 --> 00:01:21,330
Type qualifiers are also item potent.
20
00:01:21,330 --> 00:01:23,210
This was added in C99.
21
00:01:23,210 --> 00:01:27,210
What this means is that you can use the same qualifier more than once in a declaration
22
00:01:27,210 --> 00:01:29,870
and the superfluous ones are ignored.
23
00:01:29,870 --> 00:01:33,230
Okay, and we'll see an example of that. So let's talk about const.
24
00:01:33,890 --> 00:01:36,890
So the compiler allows you to associate the const qualifier
25
00:01:36,890 --> 00:01:40,390
with variables whose values will not be changed by the program.
26
00:01:40,990 --> 00:01:43,760
Okay, you can tell the compiler basically that this variable
27
00:01:43,760 --> 00:01:46,760
is going to have the same value throughout the entire program's execution,
28
00:01:46,760 --> 00:01:47,960
it's going to be constant.
29
00:01:49,160 --> 00:01:51,520
If you try to assign a value to this variable
30
00:01:51,520 --> 00:01:54,880
after initializing it, the compiler is going to give you an error.
31
00:01:56,130 --> 00:01:59,490
It doesn't always require to do so depending on what compiler you're going to give,
32
00:01:59,490 --> 00:02:02,590
but most of them will give you an error saying hey this is a constant variable
33
00:02:02,590 --> 00:02:05,590
you cannot change the value after it's been initialized.
34
00:02:06,090 --> 00:02:08,090
One of the motivations for the constant attribute
35
00:02:08,090 --> 00:02:13,750
in the c language is that it allows the compiler to place your constant variables into read-only memory.
36
00:02:13,750 --> 00:02:15,750
So it's a compiler optimization.
37
00:02:16,350 --> 00:02:19,650
If you have read-only memory, you don't have to worry about writes happening to it.
38
00:02:19,950 --> 00:02:23,950
So let's look at some examples of how you can create these constants and use them.
39
00:02:25,610 --> 00:02:28,610
So to create a constant, here we have our codeblocks problem,
40
00:02:28,610 --> 00:02:30,970
all you have to do is use that const keyword.
41
00:02:30,970 --> 00:02:34,770
So we can say const and a very popular one
42
00:02:34,770 --> 00:02:39,470
is pi because pi is a const. You specify the data type after the keyword const.
43
00:02:39,470 --> 00:02:41,020
We're going to create a double.
44
00:02:41,020 --> 00:02:43,020
We're going to say pi, and we're just going to say it's equal to
45
00:02:43,020 --> 00:02:49,020
3.141592654 which is
46
00:02:49,020 --> 00:02:52,520
pi in most things. This declares the const variable pi.
47
00:02:52,520 --> 00:02:56,820
Again, it tells the compiler that this variable cannot be modified by the program.
48
00:02:57,520 --> 00:03:00,520
So if you try to do something later in the program,
49
00:03:00,520 --> 00:03:04,420
like change the value by saying pi equals pi divided by two,
50
00:03:05,120 --> 00:03:09,320
you're not allowed to do that. So when you try to build it, the compiler is going to say
51
00:03:09,320 --> 00:03:12,920
assignment of read-only variable. You're not allowed to do that.
52
00:03:12,920 --> 00:03:14,920
The gcc compiler gives an error.
53
00:03:15,520 --> 00:03:20,510
So you can use this const keyword to create an array also of data that the program cannot alter.
54
00:03:20,510 --> 00:03:24,710
So say we wanted to create an array using this keyword. We could do something like
55
00:03:26,070 --> 00:03:29,070
const int days
56
00:03:29,470 --> 00:03:32,570
which is an array we could set the size to 12
57
00:03:32,570 --> 00:03:34,770
and then we could initialize it
58
00:03:34,770 --> 00:03:38,430
to the days of the month. We could say 31 28
59
00:03:38,430 --> 00:03:42,430
31 30 dot dot dot.
60
00:03:42,430 --> 00:03:45,430
And this will set the array to constant values.
61
00:03:45,430 --> 00:03:49,090
You can now not change any elements in the array.
62
00:03:49,090 --> 00:03:52,090
You want to be able to access the index and change the elements.
63
00:03:52,890 --> 00:03:57,090
Now I also mentioned that these constant keywords and the type qualifiers in general
64
00:03:57,090 --> 00:03:58,090
are item potent.
65
00:03:58,090 --> 00:04:01,750
So that means you can add the type qualifier as many times as you want
66
00:04:01,750 --> 00:04:02,750
and it doesn't affect it.
67
00:04:02,750 --> 00:04:07,050
So I could say const const const
68
00:04:07,050 --> 00:04:11,550
const as many times as I want and that's the exact same as saying
69
00:04:11,550 --> 00:04:13,110
const double pi.
70
00:04:14,610 --> 00:04:16,210
The compiler doesn't care.
71
00:04:18,810 --> 00:04:21,170
So it makes it possible basically
72
00:04:21,170 --> 00:04:24,170
to do different things like allowing typedef
73
00:04:24,170 --> 00:04:29,170
to be specified. So we could do something like this. We could say typedef
74
00:04:29,970 --> 00:04:31,570
const int zip.
75
00:04:33,070 --> 00:04:37,070
And then we can say const zip q
76
00:04:37,070 --> 00:04:38,270
equals eight.
77
00:04:38,270 --> 00:04:42,770
And in theory that's actually doing const twice right because zip is
78
00:04:43,070 --> 00:04:44,670
identified as a constant int.
79
00:04:45,470 --> 00:04:50,370
It's another name for const int. So if we say const zip that's really saying constant const in.
80
00:04:51,170 --> 00:04:53,370
And you'll notice if you try to compile this,
81
00:04:55,370 --> 00:04:57,970
you're perfectly fine, nothing happens. You can say build
82
00:04:58,770 --> 00:05:02,770
and it doesn't matter that those things are messed up. You have to spell typedef correctly.
83
00:05:02,770 --> 00:05:05,270
But if you spell typedef correctly, you're good to go.
84
00:05:05,870 --> 00:05:07,870
So that's what it means to be item potent.
85
00:05:08,870 --> 00:05:13,530
We have some warnings because we're not actually using any of these variables.
86
00:05:13,530 --> 00:05:17,530
And it will even give you some warnings for that potent stuff,
87
00:05:17,530 --> 00:05:19,030
but it doesn't give you an error.
88
00:05:19,530 --> 00:05:22,190
So I showed you how you can use this constant keyword on
89
00:05:22,190 --> 00:05:24,390
simple variables and arrays.
90
00:05:24,390 --> 00:05:26,750
You can also use the constant with a pointer.
91
00:05:26,750 --> 00:05:31,550
With pointers, it's a bit more complicated because you have to distinguish between making the pointer itself constant
92
00:05:31,550 --> 00:05:34,150
and making the value that is pointed to constant.
93
00:05:34,650 --> 00:05:38,950
So for example, if we wanted to apply constant to a pointer
94
00:05:38,950 --> 00:05:40,610
and we do something like this,
95
00:05:41,510 --> 00:05:44,710
const float star pf,
96
00:05:45,310 --> 00:05:49,910
so what this is doing is it's establishing that pf points to a value that must remain constant.
97
00:05:50,510 --> 00:05:53,310
So the value of pf itself can be changed
98
00:05:53,310 --> 00:05:56,810
it can be set to point at another constant value.
99
00:05:57,810 --> 00:06:02,110
So remember the difference with pointers. Pointers have values which are addresses.
100
00:06:02,510 --> 00:06:05,510
And then the address is pointing to a particular value.
101
00:06:06,510 --> 00:06:09,870
What it's pointing to cannot change when you do the syntax.
102
00:06:09,870 --> 00:06:14,770
You can't change the address, the value of the pointer itself, understand that distinct point.
103
00:06:14,770 --> 00:06:17,970
Now if we declare a pointer like this.
104
00:06:17,970 --> 00:06:21,570
If we say float star constant pt,
105
00:06:22,070 --> 00:06:25,070
this is saying pt is a constant pointer.
106
00:06:25,970 --> 00:06:30,570
So what this is saying is that the pointer pt itself cannot have its value changed,
107
00:06:31,170 --> 00:06:35,170
so that means the address can't change. It must always point to the same address.
108
00:06:35,170 --> 00:06:38,770
The pointed to value can change but not the address.
109
00:06:38,770 --> 00:06:41,770
So it's really important where you place that asterisk.
110
00:06:42,430 --> 00:06:45,430
If you place the asterisk before the constant, you can't change the address.
111
00:06:45,430 --> 00:06:49,030
If you place the asterisk after the const keyword,
112
00:06:49,030 --> 00:06:51,630
that means you can't change the value that the pointer is pointing to.
113
00:06:52,630 --> 00:06:56,990
Now what if we do something like this to make it even more confusing. What if we say constant
114
00:06:56,990 --> 00:07:01,090
float star constant pointer,
115
00:07:01,090 --> 00:07:02,650
something like that.
116
00:07:02,650 --> 00:07:05,950
That basically means that the pointer must always point to the same location
117
00:07:05,950 --> 00:07:08,950
and that the value stored at the location must also not change.
118
00:07:08,950 --> 00:07:12,250
So both are constant, and that's perfectly legal to do.
119
00:07:13,250 --> 00:07:16,250
And then the last thing I wanted to mention about pointers and constants
120
00:07:16,250 --> 00:07:18,250
is you can actually do something like this.
121
00:07:21,250 --> 00:07:25,250
And this is the same as const float
122
00:07:25,250 --> 00:07:26,750
star pfc.
123
00:07:28,750 --> 00:07:30,550
So it doesn't matter the order
124
00:07:30,550 --> 00:07:33,910
of the constant. It's either constant float or float constant.
125
00:07:34,510 --> 00:07:38,870
They're both equivalent. Placing the constant after the type name and before the star
126
00:07:38,870 --> 00:07:41,990
means the pointer cannot be used to change the pointer to value.
127
00:07:41,990 --> 00:07:45,590
A constant anywhere to the left of the star makes the data constant.
128
00:07:45,990 --> 00:07:49,290
So a constant to the right of star makes the pointer itself constant.
129
00:07:49,290 --> 00:07:51,290
Understand those distinctions.
130
00:07:51,290 --> 00:07:54,290
Where constants placed in relation to the star.
131
00:07:55,890 --> 00:07:58,690
Now what about if we want to use the constant keyword with parameter
132
00:07:58,690 --> 00:08:00,690
declarations and this is very, very common.
133
00:08:01,090 --> 00:08:03,390
So we can use constant keyword
134
00:08:03,390 --> 00:08:06,490
in declaring pointers that serve as formal function parameters.
135
00:08:06,490 --> 00:08:10,490
The formal function parameters are the ones in the function prototype.
136
00:08:10,490 --> 00:08:14,850
So for example say you have a function called display that displays the contents of an array.
137
00:08:14,850 --> 00:08:18,450
In order to use it, you would pass the name of the array as an actual argument,
138
00:08:18,450 --> 00:08:20,110
but the name of the array is an address
139
00:08:21,410 --> 00:08:24,770
and that would enable the function altered data in the calling function,
140
00:08:24,770 --> 00:08:28,770
you would be able to alter that array. So if you didn't want to alter that array,
141
00:08:28,770 --> 00:08:32,970
what you would do is for that display function, you would say void display
142
00:08:33,630 --> 00:08:36,630
and then you would say const int array
143
00:08:38,230 --> 00:08:40,230
and then maybe another parameter is the limit.
144
00:08:40,230 --> 00:08:43,230
You don't want the array to change.
145
00:08:43,830 --> 00:08:46,830
So this parameter declaration constant array
146
00:08:47,430 --> 00:08:50,790
right here is the same as const int star array.
147
00:08:52,390 --> 00:08:55,890
So the declaration is basically saying that the data to which the array points
148
00:08:55,890 --> 00:08:57,390
cannot be changed.
149
00:08:59,380 --> 00:09:02,740
And this is the practice that ANSI c library follows,
150
00:09:02,740 --> 00:09:06,740
so ANSI is the standard. So if a pointer is used only
151
00:09:06,740 --> 00:09:08,940
to give a function access to values,
152
00:09:08,940 --> 00:09:11,940
the pointer is declared as a pointer to a constant qualified type.
153
00:09:12,840 --> 00:09:15,440
If the pointer is used to alter data in the calling function,
154
00:09:15,440 --> 00:09:17,440
the constant keyword is not used.
155
00:09:18,440 --> 00:09:21,740
So for example if you have something like this char,
156
00:09:22,240 --> 00:09:26,740
it returns a char strcat, this is part of the ANSI library,
157
00:09:27,400 --> 00:09:30,400
it may say something like restrict.
158
00:09:31,760 --> 00:09:35,760
This is the actual definition. And then it has a constant for the second one,
159
00:09:36,660 --> 00:09:40,060
constant charstar restrict
160
00:09:40,060 --> 00:09:42,660
s2 and we haven't talked about restrict yet but we will.
161
00:09:42,660 --> 00:09:45,160
That's the actual function prototype for strcat.
162
00:09:45,660 --> 00:09:49,860
Remember, this function will add a copy of the second string to the end of the first string,
163
00:09:50,220 --> 00:09:51,220
s2 to s1.
164
00:09:51,580 --> 00:09:54,580
It will modify the first string and that's why it's not a constant.
165
00:09:54,580 --> 00:09:57,080
But the second string is just read only.
166
00:09:57,640 --> 00:09:59,640
The second string doesn't change s2.
167
00:10:00,140 --> 00:10:05,340
And so that's why the declaration for the second parameter is constant.
168
00:10:06,110 --> 00:10:08,710
We can also use constant with global data.
169
00:10:08,960 --> 00:10:12,460
So remember global data is just a variable that's defined at the top
170
00:10:13,060 --> 00:10:17,660
of a file. And global data is very risky. It really shouldn't be used because of maintenance
171
00:10:17,660 --> 00:10:22,060
and you sometimes will alter pro program data when you don't mean to.
172
00:10:22,460 --> 00:10:26,260
But however, when you have a global variable and it's a constant
173
00:10:26,260 --> 00:10:28,220
that risk goes away quite a bit.
174
00:10:28,880 --> 00:10:33,380
So it's perfectly reasonable to use global variables with the const qualifier.
175
00:10:34,040 --> 00:10:36,700
And you should actually try to do it if it's read only
176
00:10:36,700 --> 00:10:40,000
because this makes the global data uses definitely less risky.
177
00:10:41,660 --> 00:10:46,430
If you're using global data across files, then you have to be very, very careful.
178
00:10:46,430 --> 00:10:50,930
So if you use the external keyword, you have to be very careful with constant.
179
00:10:50,930 --> 00:10:54,590
So one approach is to use defining declarations in one file
180
00:10:54,590 --> 00:10:58,590
and reference declarations using the external keyword and the others, we know how to do that.
181
00:10:59,190 --> 00:11:02,490
So for example, we could have one file here, we could have our
182
00:11:02,490 --> 00:11:05,790
main.c file here and we could have some constants.
183
00:11:06,590 --> 00:11:10,250
So say we have some global variables, constant double pi
184
00:11:10,250 --> 00:11:12,250
and we have an array of constants.
185
00:11:12,610 --> 00:11:17,270
We'll say we have another file. Let's create another file, and this is called other.c.
186
00:11:18,570 --> 00:11:22,770
If we want to use the global constants elsewhere, we have to do something like this,
187
00:11:22,770 --> 00:11:27,130
extern const double pi. We have make sure that we refer to as constants.
188
00:11:29,330 --> 00:11:33,330
You have to follow that practice. In the first file, they're constants.
189
00:11:33,330 --> 00:11:35,930
In the second file, they have to be defined as extern constant.
190
00:11:36,730 --> 00:11:40,730
Now if you don't want to do this and sharing by files, you can actually put them in include file.
191
00:11:41,230 --> 00:11:43,430
So we could have a header file here.
192
00:11:45,420 --> 00:11:47,080
So here we have header.h.
193
00:11:47,740 --> 00:11:51,940
And we can actually put all of our constants in here which would be a better approach.
194
00:11:52,940 --> 00:11:56,060
So here we have static double,
195
00:11:56,060 --> 00:11:58,720
static constant doubles pi and months.
196
00:11:58,720 --> 00:12:03,220
We put them in the header, but we save them. And then if we want to use them in the main,
197
00:12:03,220 --> 00:12:05,720
all we have to do is say include constant.h.
198
00:12:06,320 --> 00:12:10,320
We know how to include header files. And so that's a better approach.
199
00:12:11,920 --> 00:12:15,470
Okay, and in the header, you'll notice that we use the keyword static.
200
00:12:15,970 --> 00:12:18,570
If you do not use the keyword static in the header file,
201
00:12:19,370 --> 00:12:21,370
in file one and file two,
202
00:12:21,370 --> 00:12:26,470
you'd have that would result in each file having a defining declaration of the same identifier.
203
00:12:26,870 --> 00:12:31,530
So by making these static external, you actually give each file
204
00:12:31,530 --> 00:12:33,130
a separate copy of the data.
205
00:12:33,530 --> 00:12:37,430
So this would not work if the files are supposed to use the data to communicate with another.
206
00:12:37,430 --> 00:12:40,730
So because the data is constant by using this constant keyword obviously,
207
00:12:41,390 --> 00:12:45,990
and identical by having both files include the same header file, it's not a problem.
208
00:12:46,790 --> 00:12:50,590
So the advantage of using this header file approach is that you do not have to remember
209
00:12:50,590 --> 00:12:54,580
to use defining declarations in one file and the extern in the other file.
210
00:12:55,580 --> 00:12:58,580
All the files simply include the same header file.
211
00:12:59,080 --> 00:13:01,680
The disadvantage is that you do have some duplication of data.
212
00:13:03,180 --> 00:13:07,780
And what you should have noticed throughout this lecture is const seems very, very familiar to define.
213
00:13:07,780 --> 00:13:11,580
Remember, we talked about the defined preprocessor command,
214
00:13:11,580 --> 00:13:13,240
they seem like they're very similar.
215
00:13:13,240 --> 00:13:15,540
And I kind of mentioned earlier how they're a little bit different,
216
00:13:15,540 --> 00:13:18,040
but let's take a look at how they are different.
217
00:13:19,700 --> 00:13:22,060
So the relationship between these two
218
00:13:22,060 --> 00:13:26,720
defined as a preprocessor directive constant is a keyword. We know that right off the bat.
219
00:13:26,720 --> 00:13:30,520
Constant variables are actually variables like any other normal variable.
220
00:13:30,520 --> 00:13:32,770
We can pass them around, we can typecast them
221
00:13:32,770 --> 00:13:35,770
and any other thing that can be done with a normal variable we can do.
222
00:13:36,370 --> 00:13:40,380
Define is not scope controlled, whereas constant is scope controlled.
223
00:13:40,380 --> 00:13:43,740
So what that means is define can be used anywhere in the program
224
00:13:43,740 --> 00:13:46,740
or in other files just by including that related header file.
225
00:13:47,340 --> 00:13:51,540
A constant can be declared inside a function and it can only be used inside that function.
226
00:13:51,540 --> 00:13:54,140
So there is scope related to constant.
227
00:13:55,040 --> 00:13:57,700
Another advantage of using constant over define
228
00:13:57,700 --> 00:14:00,900
is that the constant variable provides type checking by the compiler.
229
00:14:00,900 --> 00:14:03,400
But because define is a preprocessor directive,
230
00:14:03,400 --> 00:14:07,300
it happens before the compiler even gets invoked, so there's no type checking.
231
00:14:08,660 --> 00:14:14,060
Also in the past, we have discussed situations when define cannot be replaced by constant.
232
00:14:14,060 --> 00:14:17,060
I gave some examples in our define lecture where
233
00:14:17,060 --> 00:14:20,560
define does not work in certain situations,
234
00:14:20,560 --> 00:14:22,560
you have to use constant.
235
00:14:23,460 --> 00:14:27,460
So here was a lecture on the advantages and the use of constant
236
00:14:27,460 --> 00:14:31,460
with pointers and regular variables and so forth. Thank you.
22916
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.