Reputation: 15
using g++ compiler and code is compiling and running successfully. as I know that C doesn't have separate data type for string and stores the string as an array of character I don't know why the heck this is compiling without initializing the char as array.
#include <stdio.h>
int main(){
int total_ch=0;
int total_courses=2;
float sum=0.0;
float gpa=0.0;
for(int i=0;i < total_courses; i++){
printf("%d \n",total_courses);
char course;
int marks=0;
int ch=0;
float cgpa=0.0;
printf("Enter the course name: \n");
scanf(" %s",course);
printf("Enter the credit hours of the course\n");
scanf(" %d",&ch);
printf("Enter the marks of the course\n");
scanf(" %d",&marks);
total_ch += ch;
if (marks > 85){
printf("Your Cgpa of %s is 4.00 and your grade is A\n",&course);
sum+=(ch*4.00);
}else if (marks > 79 && marks < 86 ){
printf("Your Cgpa of %s is 3.67 and your grade is A-\n",&course);
sum+=(ch*3.67);
}else if (marks > 75 && marks < 80){
printf("Your Cgpa of %s is 3.33 and your grade is B+\n",&course);
sum+=(ch*3.33);
}else if (marks > 71 && marks < 76){
printf("Your Cgpa of %s is 3.00 and your grade is B\n",&course);
sum+=(ch*3.00);
}else if (marks > 67 && marks < 72){
printf("Your Cgpa of %s is 2.67 and your grade is B-\n",&course);
sum+=(ch*2.67);
}else if (marks > 63 && marks < 68){
printf("Your Cgpa of %s is 2.50 and your grade is C+\n",&course);
sum+=(ch*2.50);
}else if (marks > 59 && marks < 64){
printf("Your Cgpa of %s is 2.00 and your grade is C\n",&course);
sum+=(ch*2.00);
}else if (marks > 56 && marks < 60){
printf("Your Cgpa of %s is 1.67 and your grade is C-\n",&course);
sum+=(ch*1.67);
}else if (marks > 53 && marks < 57){
printf("Your Cgpa of %s is 1.33 and your grade is D+\n",&course);
sum+=(ch*1.33);
}else if (marks > 49 && marks < 54){
printf("Your Cgpa of %s is 1.00 and your grade is D\n",&course);
sum+=(ch*1.00);
}else if (marks < 50){
printf("Your Cgpa of %s is 0.00 and your grade is F\n",&course);
sum+=(ch*0.0);
}
}
gpa=sum/total_ch;
printf("Your total GPA of this semester is %f",gpa);
}
Upvotes: 0
Views: 82
Reputation: 180878
So why does the compiler allow this at all?
C is a very old language, by today's standards. Undefined Behavior is an artifact of the days when you could write a program that conformed to the quirks of a specific machine, without having to worry about the compiler complaining.
In the early versions of C, undefined behavior's primary advantage was the production of performant compilers for a wide variety of machines: a specific construct could be mapped to a machine-specific feature, and the compiler did not have to generate additional code for the runtime to adapt the side effects to match semantics imposed by the language. The program source code was written with prior knowledge of the specific compiler and of the platforms that it would support.
https://en.wikipedia.org/wiki/Undefined_behavior
The article goes on to say that
For C and C++, the compiler is allowed to give a compile-time diagnostic in these cases, but is not required to: the implementation will be considered correct whatever it does in such cases, analogous to don't-care terms in digital logic. It is the responsibility of the programmer to write code that never invokes undefined behavior, although compiler implementations are allowed to issue diagnostics when this happens.
Which is why you should always compile with warnings on.
Upvotes: 1
Reputation: 3382
The reason why this doesn't work is because strings are stored as char pointers but you pass just a char variable to the scanf
method. This doesn't result in a compile time error but a warning must have been issued. Make sure you pass in a valid char array with an adequate size to store the course name. For example: char course[100];
Upvotes: 0
Reputation: 7549
The variable declared in the program
char course;
is a variable that holds just a single character. It is not an array of char, nor a generic string (unless you are fine with 1-character string). So there is no initialized array, because there is no array.
To have a C-style string, that is, an array of char, you have to declare something like
char course[100];
This will declare an array of 100 chars, uninitialied of course.
In the program you posted, if you compile with enabled warnings, you will see immediately this:
main.cpp:17:10: warning: format '%s' expects argument of type 'char*', but argument 2 has type 'int' [-Wformat=]
17 | scanf(" %s",course);
You have two problems here: first you should pass a pointer to char, where the string is stored. By passing course
the compiler converts it to a pointer, and writes the read string who-knows-where, leading to UB.
Secondly, if you pass a pointer to char, you should make sure that it points to an allocated area of memory, long enough to store the result. E.g.:
char course[100];
scanf("%s", course);
But that has also a problem: what happens if the result of scanf
exceeds the allocated size 100? Then, you will run into a buffer overflow, again UB.
In fact, this is a major problem in using scanf
to read a string. See this question and the accepted answer for better alternatives.
Upvotes: 1