zyBook Programming in C

¡Supera tus tareas y exámenes ahora con Quizwiz!

2.3 Identifiers

2.3 Identifiers

3) How many commands will execute when threeintsfcts.h is changed?

3 threeintsfcts.h is a prerequisite to threeintsfcts.o and main.o. Those two rules' commands will execute, changing both .o files. Those .o files are prerequisites to myprog.exe, whose command will execute. So 2 + 1 = 3.

Rules for identifiers

A name created by a programmer for an item like a variable or function is called an identifier. An identifier must: be a sequence of letters (a-z, A-Z), underscores (_), and digits (0-9) start with a letter or underscore Note that "_", called an underscore, is considered to be a letter. Identifiers are case sensitive, meaning upper and lower case letters differ. So numCats and NumCats are different.

A reserved word is a word that is part of the language, like int, short, or double. A reserved word is also known as a keyword. A programmer cannot use a reserved word as an identifier. Many language editors will automatically color a program's reserved words. A list of reserved words appears at the end of this section.

A reserved word is a word that is part of the language, like int, short, or double. A reserved word is also known as a keyword. A programmer cannot use a reserved word as an identifier. Many language editors will automatically color a program's reserved words. A list of reserved words appears at the end of this section.

12.4 The #define directive

The #define directive, of the form #define MACROIDENTIFIER replacement, instructs the processor to replace any occurrence of MACROIDENTIFIER in the subsequent program code by the replacement text. Construct 12.4.1: #define directive. #define MACROIDENTIFIER replacement

A common error is to use spaces instead of a single tab character for specifying the commands. Another common error is including a tab character on an empty line, which will be reported by make as an error. As distinguishing between tabs and spaces in some text editors can be difficult, these errors are often challenging to find.

The following provides an example makefile for a program consisting of three files main.c, threeintsfcts.c, and threeintsfcts.h. The executable named myprog.exe is dependent on the object files main.o and threeintsfcts.o. The main.o object file is dependent on the main.c source file and the threeintsfcts.h header file. The threeintsfcts.o object file is dependent on the threeintsfcts.c and threeintsfcts.h files.

1) A single-step compilation approach is faster than a modular compilation approach.

false. In a single-step compilation approach, anytime one of the source files is modified, all files must be recompiled. In a modular compilation approach, each source file is independently compiled so only source files that are updated need to be recompiled.

4) The call CalcCircleArea(PI_CONST) would yield a compiler error complaining that the macro cannot be an argument.

false. PI_CONST is a valid identifier in an expression, and thus is a valid argument in a function call.

3) Replacing the return expression by PI_CONSTPI_CONST would yield 3.141593.14159, which would thus yield a compiler error complaining about the two decimal points.

false. The preprocessor recognizes PI_CONSTPI_CONST as its own identifier, and thus would not replace that identifier with 3.14159.

2) Replacing the return expression by PI_CONST * PI_CONST * radius yields a compiler error since only one replacement is allowed.

false. The preprocessor replaces all occurrences of the PI_CONST identifier.

2) What command will execute after threeintsfcts.o is changed? (Hint: The answer starts with gcc.)

gcc main.o threeintsfcts.o -o myprog.exe threeintsfcts.o is a prerequisite of myprog.exe, so that rule's command will execute.

12.5.2: Modular compilation process.

https://drive.google.com/file/d/1fxloEcAb1ewqYrlkQ5K3lFXLjeS7JEzF/view?usp=sharing https://drive.google.com/file/d/1CNxTAJv379IszqFh0szfnxH8cUEcPxba/view?usp=sharing https://drive.google.com/file/d/1ajCjCZoW9UFcGoWylR444IPorRTwoK-C/view?usp=sharing https://drive.google.com/file/d/1ypRShTGdEJwZdMMjlAjSBGoWiM4jxwvi/view?usp=sharing https://drive.google.com/file/d/1wnmkKu5fignpw-fVJQbvBf7O2r-OimUq/view?usp=sharing

Figure 12.6.1: Makefile example for three integer functions program.

https://drive.google.com/file/d/1icwuRiVuJdZUDFzIaRqhvxNS4S5SHAYI/view?usp=sharing

The make utility uses a makefile to recompile and link a program whenever changes are made to the source or header files. The makefile consists of a set of rules and commands. Make rules are used to specify dependencies between a target file (e.g., object files and executable) and a set of prerequisite files that are needed to generate the target file (e.g., source and header files). A make rule can include one or more commands -- referred to as make recipe -- that will be executed in order to generate the target file. The following shows the general form for a make rule. The make rule's target and prerequisites are defined on a single line. The commands for the make rule should be specified one per line starting with a single tab character.

Construct 12.6.1: Makefile rules and commands. https://drive.google.com/file/d/1YO20umjtFHkKKISLrHjDVWqPO3XweEYZ/view?usp=sharing

3) A linker is responsible for creating object files.

FALSE. A linker is responsible for linking together the object files and libraries. For each placeholder found with an object file, the linker searches the other object files and libraries to find the referenced function or variable.

define is sometimes called a macro. The #define line does not end with a semicolon. Most uses of #define are strongly discouraged by experienced programmers. However, for legacy reasons, #define appears in much existing code, so a programmer still benefits from understanding #define.

One (discouraged) use of #define is for a constant. The directive #define MAXNUM 99 causes the preprocessor to replace every occurrence of identifier MAXNUM by 99, before continuing with compilation. So if (x < MAXNUM) will be replaced by if (x < 99). In contrast, declaring a constant variable const int MAXNUM = 99 has several advantages over a macro, such as type checking, syntax errors for certain incorrect usages, and more.

As programs become larger and the number of source files increases, the time required to recompile and link all source files can become very long - often requiring minutes to hours. Instead of compiling an executable using a single step, a modular compilation approach can be used that separates the compiling and linking steps within the compilation process. In this approach, each source file is independently compiled into an object file. An object file contains machine instructions for the compiled code along with placeholders, often referred to as references, for calls to functions or accesses to variables or classes defined in other source files or libraries.

For a program involving two files main.c and threenumsfcts.c, the files can be compiled separately into two object files named main.o and threenumsfcts.o respectively. The resulting object files will include several placeholders for functions that are defined in other files. For example, the main.o object file may contain placeholders for calls to any functions in threenumsfcts.o. After each source file has been compiled, the linker will create the final executable by linking together the object files and libraries. For each placeholder found within an object file, the linker searches the other object files and libraries to find the referenced function or variable. When linking the main.o and threenumsfcts.o files, the placeholder for a call to a function in main.o will be replaced with a jump to the first instruction of that function within the threenumsfcts.o object file. This creates a link between the code within the main.o and threenumsfcts.o object files. Once all placeholders have been linked together, the final executable can be created. The following animation illustrates.

5) Placing a semicolon at the end of the #define line will yield a compiler error at that line.

Instead, the compiler will replace PI_CONST with 3.14159;, thus creating this line: return PI_CONST; * radius * radius; That line will then generate a syntax error.

When the make command is executed, if any of the prerequisites for the rule have been modified since the target was last created, the commands for the rule will be executed to create the target file. For example, in the above makefile, if main.c is modified make will first execute the command gcc -Wall -c main.c to create the main.o object file. The -c flag is used here to inform the compiler (e.g. gcc) that the source file should only be compiled (and not linked) to create an object file. As main.o has now been modified, make will then execute the command gcc main.o threeintsfcts.o -o myprog.exe. The -o flag is used here to inform the linker (e.g. gcc) to link the object files into the final executable using the name specified after the -o. In this case, the executable is named myprog.exe.

Make rules can also be used to define common operations used when managing larger programs. One common make rule is the clean : rule that is used to execute a command for deleting all generated files such as object files and the program executable. In the above example, this is accomplished by running the command rm *.o myprog.exe. By default make assumes the makefile is named makefile or Makefile. The -f flag can be used to run make using a different filename. For example, make -f MyMakefile will run make using the file named MyMakefile.

One (discouraged) use of #define is for a constant. The directive #define MAXNUM 99 causes the preprocessor to replace every occurrence of identifier MAXNUM by 99, before continuing with compilation. So if (x < MAXNUM) will be replaced by if (x < 99). In contrast, declaring a constant variable const int MAXNUM = 99 has several advantages over a macro, such as type checking, syntax errors for certain incorrect usages, and more.

One (discouraged) use of #define is for a constant. The directive #define MAXNUM 99 causes the preprocessor to replace every occurrence of identifier MAXNUM by 99, before continuing with compilation. So if (x < MAXNUM) will be replaced by if (x < 99). In contrast, declaring a constant variable const int MAXNUM = 99 has several advantages over a macro, such as type checking, syntax errors for certain incorrect usages, and more.

Given:#define PI_CONST 3.14159 double CalcCircleArea(double radius) { return PI_CONST * radius * radius; } 1) The function call CalcCircleArea(1.0) returns 3.14159. True False

True. The preprocessor replaces PI_CONST by 3.14159, so CalcCircleArea() returns 3.14159 * 1.0 * 1.0, or 3.14159.

12.5 Modular compilation

Using separate files to organize code can also help to make the compilation process more efficient. So far, we used a single-step compilation approach in which all source files are compiled at the same time to create the executable, e.g. gcc main.c threenumsfcts.c. This approach has a significant drawback. Anytime one of the source files is modified, all files must be recompiled. Even a small change, such as modifying a printf statement to fix a spelling error, would require all files be recompiled. The following animation illustrates the single-step compilation.

12.6 Makefiles

While modular compilation offers many advantages, manually compiling and linking a program with numerous source and header files can be challenging. For example, a change within a single header file will require recompiling all source files that include that header file. Keeping track of these dependencies to determine which files need to be recompiled is not trivial and can require considerable effort, if done manually. For large programs, programmers often utilize project management tools to automate the compilation and linking process. make is one project management tool that is commonly used on Unix and Linux computer systems.

(UP) Answer the following using the Makefile provided above. 1) List the targets affected if main.c is changed. (Note: List the targets separated by spaces and in the order that their rules would execute.)

main.o myprog.exe main.o is affected because main.cpp is a prerequisite for main.o. Because main.o's command will modify main.o, then myprog.exe will be affected because main.o is a prerequisite of myprog.exe.

2) An object file contains machine instructions for the compiled code, along with references to functions or access to variables or classes in other files or libraries.

true. Each source file is compiled into a separate object file.


Conjuntos de estudio relacionados

Ch 5: Practical Applications of Classical Conditioning

View Set

AMSCO Chapter 24, AMSCO Chapter 18, Chapter 23 Multiple Choice, Chapter 24 Multiple Choice Questions

View Set

CS: Benign Prostatic Hyperplasia

View Set

CompTIA Security+ Practice Test #2

View Set

CIS 3343 Exam 2 Review (Chapter 8)

View Set

Present Simple and Present Progressive

View Set

Trivia Murder Party 2 Questions and Answers

View Set

Adolescent Psychology Chapter 8, Psych 21A - Chapter 8, Chapter 8: Identity

View Set

Business Intelligence & Data Warehousing

View Set