munotes®

Constants and Their Types

Chapter Ten

Syllabus topic 1, "Introduction: Algorithms, History of C, Structure of C Program. Program Characteristics, Compiler, Linker and preprocessor, pseudo code statements and flowchart symbols, Desirable program characteristics. Program structure. Compilation and Execution of a Program, C Character Set, identifiers and keywords, data types and sizes, constants and its types, variables, Character and character strings, typedef, typecasting"

Pages 45 to 49 of 222

In one line

A constant is a value written directly into the program, which cannot change while the program runs, and the way you write it decides its type.

Why the way you write it matters

printf("%d\n", 7 / 2) prints 3. Not 3.5, and it is not a bug. Both operands are integer constants, so C does integer division, which throws the fraction away. Write 7.0 / 2 and you get 3.5, because 7.0 is a double.

The value is the same number in both cases. The type is different, and the type decides what the operators do with it. That is why this chapter comes before the operators.

Integer constants

A whole number with no decimal point and no exponent. It may be written in three bases:

WrittenBaseValue
75decimal75
0113octal, leading zero75
0x4B or 0X4bhexadecimal, leading 0x75

A leading zero means octal, and this catches people. 011 is not eleven, it is nine. Writing a date as 09 or a zero-padded code as 0755 silently changes the number, and if a digit 8 or 9 appears the compiler reports an error on a line that looks fine.

#include <stdio.h>

int main(void)
{
    printf("75 is %d\n", 75);
    printf("0113 is %d\n", 0113);
    printf("0x4B is %d\n", 0x4B);
    printf("011 is %d, not eleven\n", 011);
    return 0;
}
75 is 75
0113 is 75
0x4B is 75
011 is 9, not eleven

Suffixes set the type. Without one, the type is the first of int, long int, long long int that the value fits in.

SuffixMeansExample
noneint, or wider if it must be100
U or uunsigned100U
L or llong100L
UL, LU and so onunsigned long100UL
LLlong long100LL
ULLunsigned long long100ULL

Prefer capital L. A lower-case l is almost indistinguishable from the digit 1 in most fonts, and l against 1 has caused real bugs.

Floating constants

A number with a decimal point, or an exponent, or both. Its type is double by default, which is a fact worth remembering: there is no way to write a float constant without saying so.

WrittenTypeValue
3.14double3.14
3.14f or 3.14Ffloat3.14
3.14Llong double3.14
1e3double1000.0
1.5e-3double0.0015
.5double0.5
5.double5.0

1e3 means 1 times ten to the third. The e may be E, and the exponent may carry a sign. Both .5 and 5. are legal, and both are clearer written as 0.5 and 5.0.

1e3 is a floating constant even though its value is a whole number. printf("%d\n", 1e3) is undefined behaviour, not a rounding question.

munotes.in45

Constants and Their Types

Character constants

A single character in single quotation marks. Its type is int, not char, which surprises everyone the first time.

#include <stdio.h>

int main(void)
{
    printf("'A' as a character is %c\n", 'A');
    printf("'A' as a number is %d\n", 'A');
    printf("sizeof('A') is %zu, and sizeof(char) is %zu\n",
           sizeof('A'), sizeof(char));
    printf("'A' + 1 is %d, and as a character %c\n", 'A' + 1, 'A' + 1);
    return 0;
}
'A' as a character is A
'A' as a number is 65
sizeof('A') is 4, and sizeof(char) is 1
'A' + 1 is 66, and as a character B

The value is the character's code in the execution character set, which is ASCII on any machine you will use. So 'A' is genuinely usable as the number 65, and '0' as 48, and that is what makes c - '0' convert a digit character into its numeric value.

An escape sequence is a character constant: '\n', '\t', '\\', '\0'. Each is one character. Chapter 7 has the list.

'A' and "A" are not the same thing. The first is one character whose value is 65. The second is a string literal: an array of two characters, A and the terminating zero. Chapter 12.

'AB' is not a string and not an error you can rely on. It is a multi-character constant, its value is implementation-defined, and -Wall warns about it. Never write one.

String literals

Text in double quotation marks. Strictly it is a literal rather than a constant, and the distinction is real: a string literal is an array of char, and an array is not a constant expression.

"Hello"

That is six characters in memory, not five: H, e, l, l, o and a terminating \0 that the compiler adds. The count of the terminator is what chapter 12 and the whole string library depend on.

A string literal must not be modified. It may be stored in read-only memory, and a program that writes into one may crash. Declare const char *s = "Hello"; when you only mean to read it.

Two string literals written next to each other are joined into one, which is how a long piece of text is spread over several source lines:

printf("This is one long line of output that would not "
       "fit comfortably in the source, so it is split.\n");

Enumeration constants

An enum declares a set of named integer constants. They are the only constants that are genuinely part of the type system rather than the syntax.

#include <stdio.h>

enum day { MON, TUE, WED, THU, FRI, SAT, SUN };
enum grade { FAIL = 0, PASS = 40, FIRST = 60, DISTINCTION = 70 };

int main(void)
{
    enum day today = WED;

    printf("MON is %d and SUN is %d\n", MON, SUN);
    printf("today is %d\n", today);
    printf("the pass mark is %d and a distinction is %d\n", PASS, DISTINCTION);
    return 0;
}
munotes.in46

Constants and Their Types

MON is 0 and SUN is 6
today is 2
the pass mark is 40 and a distinction is 70

Numbering starts at 0 and increases by one unless you set a value, and after a value that you set, counting continues from it. An enumeration constant has type int.

The three ways to name a constant, and which to use

This is the part examiners like, because the three are genuinely different.

1. #define, a preprocessor macro.

#define PI 3.14159
#define MAX_STUDENTS 60

The preprocessor replaces the name with the text. There is no type, no storage and no scope: the substitution happens everywhere below the directive, and a mistake in it is reported against the line where the name was used, not where it was defined. By convention the name is in capitals.

2. const, a qualified variable.

const double pi = 3.14159;
const int max_students = 60;

This is a real object with a real type, which the compiler will not let you assign to. It obeys scope, it appears in a debugger, and the compiler type-checks every use of it. This is the one to prefer.

3. enum, for a set of related whole numbers.

Best where the values are a group: days, states, menu choices, error codes. It gives them a type as well as values, which #define cannot.

#defineconstenum
Handled byPreprocessorCompilerCompiler
Has a typeNoYesYes, int
Obeys scopeNoYesYes
Type-checkedNoYesYes
Can be a fractionYesYesNo
Usable as an array sizeYesNot portably in CYes
Visible to a debuggerNoYesYes

The array-size row is the one real reason #define survives in C. const int n = 10; int a[n]; is a variable-length array, which C99 allows and which is not the same thing as a fixed-size array; #define N 10 and enum { N = 10 }; both give a genuine constant expression.

What this does NOT mean

A constant is not a variable that cannot change. A constant has no memory of its own; it is a value written in the program. A const variable is a variable that cannot change, which is a different thing with a confusingly similar name.

#define does not create a constant of any type. It creates a text substitution. #define HALF 1/2 used as x HALF becomes x 1/2, which is (x * 1) / 2, and for an integer x of 3 that is 1 rather than 1.5. Chapter 22 is why macro definitions get brackets round them.

munotes.in47

Constants and Their Types

A leading zero is not formatting. 0113 is octal. If you want the decimal number 113, write 113.

'A' is not of type char. In C a character constant has type int. (In C++ it is char, which is one of the few differences that shows up in a first program.)

3.14 is not a float. It is a double. Assigning it to a float narrows it, and 3.14f is how you write a float constant.

A string literal is not modifiable. char *s = "Hello"; s[0] = 'J'; compiles and may crash. Use an array if you mean to change the text: char s[] = "Hello"; copies it into memory you own.

Quick revision

  • Four kinds of constant: integer, floating, character, enumeration. String literals are a fifth thing and are arrays.
  • Integer bases: decimal, octal with a leading 0, hexadecimal with 0x. 011 is 9.
  • Integer suffixes: U, L, LL and combinations. Prefer capital L.
  • A floating constant is a double unless suffixed f or L.
  • A character constant is one character in single quotes and has type int, with the value of the character's code.
  • 'A' is 65 in ASCII; '0' is 48; c - '0' converts a digit character to a number.
  • A string literal in double quotes carries a terminating \0 and must not be modified.
  • enum numbers from 0, continues from any value you set, and has type int.
  • Three ways to name one: #define (text, no type), const (typed, scoped, preferred), enum (a typed set of ints).

Test yourself

1. What is the value of 010 + 10?

  1. 010 is octal for 8, and 10 is decimal ten.

2. What is the type of 3.14, and how do you write the same value as a float?

double. Write 3.14f.

3. What does printf("%d\n", 'a') print, and why is it not an error?

97 on an ASCII machine. A character constant has type int and its value is the character's code, so %d is the correct conversion for it.

4. How many bytes does "Hi" occupy?

Three: H, i and the terminating \0.

5. Give one thing const can do that #define cannot, and one thing #define can do that const cannot.

const has a type, so the compiler checks every use of it, and it obeys scope. #define yields a constant expression usable as a fixed array size, which a const int does not in C.

munotes.in48

Constants and Their Types

6. After enum colour { RED = 5, GREEN, BLUE };, what is BLUE?

  1. Counting continues from the value that was set, so GREEN is 6 and BLUE is 7.

7. Why does 7 / 2 give 3 while 7.0 / 2 gives 3.5?

In the first both operands are integer constants, so integer division discards the fractional part. In the second 7.0 is a double, so the 2 is converted to double and the division is done in floating point.

What can be asked on this, and how to answer it

"What is a constant? Explain the types of constants in C with examples." Define it, then give the four kinds with two examples each, and the rules that fix the type: octal and hexadecimal notation, the integer suffixes, floating constants being double by default, and a character constant having type int. Mention string literals and their terminating \0.

"Distinguish between #define and const." Give the table's rows: preprocessor against compiler, no type against a type, no scope against scope, unchecked against type-checked, and the one advantage #define keeps, which is a constant expression for an array size. Prefer const and say so.

"What is an enumeration? How are its values assigned?" A set of named integer constants declared with enum. Values start at 0, increase by one, and may be set explicitly, after which counting continues from the set value. Give a day or a grade example.

"What is the difference between 'A' and "A"?" 'A' is a character constant of type int with the value 65 in ASCII, occupying the space of an int. "A" is a string literal: an array of two char, A followed by \0. This is a favourite one-mark question.

"Write a program to show that a character constant has a numeric value." Print 'A' with both %c and %d, and 'A' + 1 as well, as this chapter does.

munotes.in49

The rest of this subject

These notes are cut from the University's printed syllabus. Open the syllabus itself for the same subject.

Report or request
Done!