Hello, and welcome back.
In this lecture, I want to talk about some common mistakes that you'll make
while programming in c.
Some of these you might be familiar with from your previous
challenges, and you've already actually encountered these errors,
but these are the most common types of mistakes.
First one is very, very obvious. It's missing a Semicolon.
Remember that all statements in c will end in a semicolon.
If you don't have it there, the compiler is going to complain.
So either misplacing a semicolon or missing a semicolon entirely
is a really common error. In this case, we're misplacing a semicolon.
We have an if statement. We put a semicolon at the end of the if statement.
And this actually causes the behavior of the program to be completely different.
This will actually compile.
When you miss a semicolon and don't even have it included, it will not compile.
But in this case, the value of j is always going to be set to zero
because the semicolon on the if statement was placed.
So the semicolon is perfectly valid to have it after the if statement.
It actually represents the null statement.
And therefore, you don't have an error by the compiler,
but this will cause a problem because j will never ever be set to zero.
And this type of mistake can be common in looping as well.
When you have a loop and you put the semicolon at the end of the for loop
and then you may have a bracket, where you don't have the bracket
because you'll have an error if you have the bracket, very common.
Another one is confusing the equals operator with the equals equals operator.
Specifically mentioned that the equals equals operator
is not comparing strings. So if you use equals equals
when you're comparing strings, that's not valid. It's just going to compare the references.
But if you actually mean to assign a value to a variable and instead use the equals equals,
you're going to have a compiler.
Now if you try to compare two items, like two integers
inside of an if statement and instead you use the assignment operator,
you actually won't have a compiler error,
but that expression is always going to evaluate to true.
So when you use the equals and you don't use the equals equals,
this is usually made in if while do statement, inside the Boolean expression.
And this is valid except it has the effect of assigning
to something as opposed to executing something.
So in this example,
if we have if a equals 2, it's assigning 2 to a.
It always set to true because that's a true statement
because you never fail when it's doing assignment. And so printf is always going to run.
What you really meant to do here is say if a equals equals to.
So it's very common using the equals as opposed
to the equals equals and then not have a compiler error.
If you use the equals equals in the wrong situation,
you may have unexpected behavior as well,
but you will have a compiler error if you're
using it to incorrectly for assignment.
But be careful of this with the equals instead of the equals equals.
Omitting prototype declarations.
I mentioned that it's really important to always declare
your functions at the top of the file before you use them.
However, this doesn't always happen and it's very common mistake.
And usually, what will happen is you'll get an implicit declaration error
in the compiler.
In this example, if you have square root defined later
in the program than where you're invoking it or in another file
and you didn't explicitly declare it,
you're going to have some warnings.
The compiler is going to assume that the function returns an int.
It's always safest to include that prototype declaration at the top
for all the functions that you call,
either explicitly
or implicitly by including the correct header file in your program.
But when you don't include that, those prototype declarations
you can have errors.
Failing to include the header file that includes the definition for a c programming
library function being used in the program.
So in this case, you want to reuse some code. Maybe you have the printf function
you want to display some output, but you do not include the standard lib header file.
That's a mistake. And that will be usually told you by the compiler.
There will be
linking problem with that function.
So in this case, we have double answer equals square root value 1.
If this program doesn't include the math.header file,
this will generate an error that square root is undefined.
It will go try to link the object files. It won't have a math.o.
And it will say, hey, you're calling the square root, but there's no implementation for it.
So make sure you include the correct headers for all of your
invocations of functions, especially from the standard library.
Confusing a character constant in a character string.
So here if we have text equals a inside single quotes,
that's a single character that's assigned to text.
If we have a variable named text and we assign in double quotes,
that's a pointer to the character string.
That is not valid
for a single character.
And this actually we've talked about
string constants and assigning them to character arrays.
And how you can't do that with the equals and you have to actually
do them with the star copy.
In this case, when we say text equals a, it's assigning a pointer
and this actually isn't valid either and see
what you would have to do is you'd have to do the star text equals a
or the star copy if you don't want to
assign it directly like that.
But you get the gist.
Using an a inside of single quotes versus a character inside double quotes
completely different, character versus string.
In the first case, text is normally declared to be a char variable.
And in the second case, it should be declared to be type pointer to a char.
And if you want to assign a value to that pointer
other than the pointer itself, you'd have to de-reference it.
This is actually incorrect because if it's a pointer
instead of assigning an address, you're assigning it a string,
so that doesn't make sense.
Using the wrong bounds for an array, array out of bounds exception.
Here, we're declaring an integer array of 100 size
and then a couple variables I and sum with only some being initialized.
And we go through our loop, we say for I equals 1 I is less than equal to 100.
That's incorrect because the size of a hundred means that there's a
hundred elements in the array. But arrays are zero based.
So the first element is zero. The max index that you can assign
or access in the a array is 99.
This is going to less than equals.
So you're going to have an out of bounds mistake here.
This is not a valid subscript
because this loop is going to go all the way to 100.
It's also probably incorrect because you're starting at 1.
If you really wanted the first element of this array, you would start at 0.
Forgetting to reserve an extra location in an array
for the terminating null character of a string
is also a common problem.
When declaring your character arrays, they need to be large enough to contain the terminating alone character.
This is why I would suggest to you
don't put a size in an array when you create it if you're initializing it.
You would only put the size in there if you're not initializing it.
If you're creating initializing on the same line, let c do the work for you,
it will automatically put the right size and it will include that null terminator.
So for example, if you have a character string called hello,
this is more than five memory locations, it's six because of that null terminator at the end.
Don't forget about the size of your arrays.
This is a common problem with pointers which we haven't discussed a ton about,
but I did want to just mention because it's very common.
In pointers, when you want to access or even instruct, when you want to access
something by a pointer,
you have to use the dash greater than symbol.
That's used when you're accessing a pointer element.
So if you have a pointer that's pointing to a structure, that's how you access it.
If you have a structure,
it's not a pointer, then you access it using a dot operator.
A lot of times this dot operator and this dash then greater than
is used incorrectly.
Dot for non-pointers, pointers dash greater than,
this will become clear in more of our examples.
Omitting the ampersand before non-pointer variables in a scanf call.
So remember our scanf call expects a pointer as a second argument,
and that means an address.
When we declare a data type a variable of type int,
that's not a pointer.
So in order to allow scanf to store that data in our int variable,
we have to pass it the ampersand to say it's an address.
So this is incorrect,
not having the ampersand before number and scan f as the second argument
is not valid. The only time you do not have the ampersand is if you're using a pointer,
like a character array.
All arguments appearing after the format string and scanf must be pointers.
Using a pointer variable before it's initialized.
So here's an example of creating a pointer and then trying to assign to it.
And this is the correct assignment where you're assigning a value you de-reference it.
But what we haven't done here is we have initialized the pointer to actually
have any memory allocated for it
and you can't do this in c.
You can only apply the indirection operator,
which is the asterisk before
to a point or variable after you have set the variable pointing somewhere.
So it has to be pointing somewhere, right now it's null it's not pointing anywhere because you didn't
allocate any memory.
So the char pointer is never set to point to anything so the assignment is not meaningful.
This would actually cause a segmentation fault.
Another common error is omitting the break statement at the end of a case in a switch statement.
If break is not included at the end of a case, then execution is continued to the next case.
So this is what I mentioned where you have a case, it gets evaluated.
And if you don't have that break in there, it goes right to the next
case and will execute the code inside that next case.
So you always want to have breaks inside your case statements.
There are times when you want to have a follow through case to another case
and they do the exact same thing,
in that case you wouldn't have anything inside the case statement.
Inserting a semicolon at the end of a preprocessor definition.
Preprocessor definitions remember start with the number,
the pound symbol. The preprocessor is run before the compiler
usually for optimization.
The correct syntax for preprocessor definitions are not to include a semicolon.
However, in c you, get into the habit of always putting a semicolon after everything.
But you got to remember that if you define some constant data
that you don't need the semicolon, this is incorrect.
This will lead to a syntax error
if it's used an expression like that.
like that. So if you actually try to use that to find
it's going to be okay to have that semicolon at the end.
But when the preprocessor runs it's going to insert exactly what is in that defined.
So it's going to serve into end of data 999 colon.
This is what the compiler is going to see it and it's going to actually cause an error,
that would be a syntax error.
Omitting a closing parenthesis or closing quotation marks on any statement,
very common. So this is also directly related to brackets too,
having a starting curly brace and then not ending the curly brace,
same thing with parentheses. In this case,
we have two starting left parentheses or three,
but we only have two ending parenthesis. We're missing an ending right parentheses.
That would be a syntax error that the compiler would find.
So when you're using embed in parentheses to set apart each portion of an equation,
it makes for a more readable line of code.
You want to use parentheses.
However, you want to make sure they all match
you start a parenthesis you have to have an ending closing parenthesis, the same with curly braces.
You start a curly brace, it has to have an ending curly brace.
So either you have too many or you have too little
but the compiler is going to complain, and this is very, very common.
So the second line here is missing a closing quotation mark as well, this print statement.
We don't have an ending quote.
The compiler will complain about that.
Both of these will generate a compile error.
Sometimes though the compiler is very misleading because it
doesn't actually know where the error occurs. It thinks the error might have occurred on a subsequent line.
So the line that it tells you the error might be misleading.
So depending on whether the compiler uses
a parenthesis or a quotation mark on a subsequent line,
it will actually complete that expression.
So it will move the error down into another line.
And that's what it will complain and say that's where the error is.But the actual error
is higher up above where you meant to place it.
These are some common mistakes that I see a lot of c programmers
making.
They're easy to fix. And if you understand them
and study this,
you'll know not to make them. It's okay to make them as a beginner,
but as you code more and more and get more practice, you'll realize,
hey, I forgot a parenthesis, I forgot a bracket,
I didn't use the equals and the equals equals correctly,
I'm using pointers incorrectly, I didn't allocate any memory.
All these things will come more second nature. Thank you.