This document provides a quick introduction to the C programming language. It begins with an overview of writing and running C programs, including compiling source code into an executable binary. It then discusses some key C programming concepts like functions, memory, variables, and data types. The document uses simple examples like a "Hello World" program to demonstrate basic C syntax and how programs are executed. Overall, it aims to give new C programmers a high-level understanding of some essential C programming fundamentals in about 3 pages.
This document is the table of contents for a book on C programming. It lists 88 example C programs that are intended to teach C concepts in an evolutionary manner. The programs cover basics like input/output, variables, data types, operators, loops, conditional statements, arrays, functions, pointers, structures, file I/O and more. The programs are presented from simplest to more complex to help programmers learn each new element of the C language.
The preprocessor performs text replacement and preprocessing directives before a C/C++ program is compiled. Key functions of the preprocessor include #include to insert external files, #define for symbolic constants and macros, and conditional compilation (#if #ifdef #ifndef etc.) to control compilation. Other directives include #error to print error messages, #pragma for compiler-specific options, and assert to check for invalid values.
The document provides an overview of how a simple C "Hello World" program works, from writing the code to executing the compiled binary. It includes explanations of key concepts like #include, main(), printf(), compiling with gcc, the a.out executable, and how the operating system loads and runs the program. The summary explores the high-level process of taking C code and turning it into a running program.
Final requirement in programming niperosmarkings17
Here is an example of a basic for loop in C++:
for (int i = 0; i < 10; i++) {
cout << i << endl;
}
This loop will print the numbers 0 through 9. It initializes the variable i to 0, checks that i is less than 10 for the condition, and increments i by 1 each iteration via i++.
This document provides an overview of the C++ programming language including its history, common features, and useful resources for learning C++. It discusses data types, classes, functions, pointers, references, operator overloading, templates, and more. Code examples are provided to illustrate key concepts. Useful online tutorials and references are listed for further learning C++.
Contains C programming tutorial for beginners with lot of examples explained. This tutorial contains each and every feature of C programming that will help you. C programming tutorial covering basic C Programming examples, data types, functions, loops, arrays, pointers, etc.
FLOW3 1.0 – scheduled for the 2nd quarter of 2011 – is an application framework aiming to back up developers with security and infrastructure while they focus on the application logic. With Domain-Driven Design as its major underlying concept, FLOW3 is easy to learn but flexible enough for complex projects.
This session from the International PHP Conference 2011 (Spring) provides a comprehensive overview of the main strengths of FLOW3.
This document is the table of contents for a book on C programming. It lists 88 example C programs that are intended to teach C concepts in an evolutionary manner. The programs cover basics like input/output, variables, data types, operators, loops, conditional statements, arrays, functions, pointers, structures, file I/O and more. The programs are presented from simplest to more complex to help programmers learn each new element of the C language.
The preprocessor performs text replacement and preprocessing directives before a C/C++ program is compiled. Key functions of the preprocessor include #include to insert external files, #define for symbolic constants and macros, and conditional compilation (#if #ifdef #ifndef etc.) to control compilation. Other directives include #error to print error messages, #pragma for compiler-specific options, and assert to check for invalid values.
The document provides an overview of how a simple C "Hello World" program works, from writing the code to executing the compiled binary. It includes explanations of key concepts like #include, main(), printf(), compiling with gcc, the a.out executable, and how the operating system loads and runs the program. The summary explores the high-level process of taking C code and turning it into a running program.
Final requirement in programming niperosmarkings17
Here is an example of a basic for loop in C++:
for (int i = 0; i < 10; i++) {
cout << i << endl;
}
This loop will print the numbers 0 through 9. It initializes the variable i to 0, checks that i is less than 10 for the condition, and increments i by 1 each iteration via i++.
This document provides an overview of the C++ programming language including its history, common features, and useful resources for learning C++. It discusses data types, classes, functions, pointers, references, operator overloading, templates, and more. Code examples are provided to illustrate key concepts. Useful online tutorials and references are listed for further learning C++.
Contains C programming tutorial for beginners with lot of examples explained. This tutorial contains each and every feature of C programming that will help you. C programming tutorial covering basic C Programming examples, data types, functions, loops, arrays, pointers, etc.
FLOW3 1.0 – scheduled for the 2nd quarter of 2011 – is an application framework aiming to back up developers with security and infrastructure while they focus on the application logic. With Domain-Driven Design as its major underlying concept, FLOW3 is easy to learn but flexible enough for complex projects.
This session from the International PHP Conference 2011 (Spring) provides a comprehensive overview of the main strengths of FLOW3.
This document discusses debugging techniques for C programs. It defines debugging as finding why a program does not work as expected after compiling without errors. Key techniques include annotating code with print statements to check execution paths and variable values, using compiler flags to enable warnings, reading error messages carefully, taking breaks when stuck, and using a debugger to view stack traces if a program crashes. Common errors like missing breaks, incorrect operator usage, and pointer issues are also outlined.
The document discusses how the Java Virtual Machine (JVM) supports dynamic languages through the invokedynamic bytecode instruction. This simplifies the implementation of compilers and runtime systems for dynamically typed languages on the JVM by allowing method dispatch to be deferred until runtime. It also describes how method handles in Java 7 provide a more efficient and flexible way to access methods compared to reflection by embedding access restrictions and allowing faster invocation and combination of methods.
This document summarizes a presentation given on why to choose Hack/HHVM over PHP7. Some key points made include:
1. Hack provides more powerful type hinting capabilities compared to PHP7, including support for nullable and mixed types.
2. Hack features original collections like Vector, Map, Set and Pair that allow specifying value types, unlike PHP arrays.
3. Hack has original language specifications like lambdas, generics, and enums not in PHP7.
4. Hack allows parallel execution out of the box for higher performance.
5. Hack's static analysis tool catches errors before runtime for more bug-free code.
6. HHVM continues to incorporate features from PHP
HHVM is a virtual machine developed by Facebook that executes PHP and Hack code faster than traditional PHP interpreters. It began as a just-in-time compiler for PHP (HipHop) and has evolved to include a bytecode interpreter and support for the Hack programming language. HHVM can be used as a drop-in replacement for PHP and supports many PHP extensions and features while offering performance improvements of up to 2x over PHP. It additionally provides static typing and type checking via the Hack language to improve code quality.
An introduction to the C programming language for the students of the course "HJ-82 Ontwerpen voor de optie multimedia en signaalverwerking: seminaries", taught by the authors at the Catholic University of Leuven.
C is a programming language developed in 1972 by Dennis Ritchie at Bell Labs. It is a structured programming language that is highly portable and supports functions. A C program consists of functions, with a main function that is the program entry point. Input/output in C uses predefined functions like printf() and scanf(). A C program is compiled into an executable file that can run on many machine architectures. The document then discusses C program structure, data types, libraries, variables, keywords, operators, and control flow statements like if/else, switch, while, do-while and for loops.
Threads and Callbacks for Embedded PythonYi-Lung Tsai
Python is a great choice to be customized plug-ins for existing applications. Extending existing applications with Python program is also practical. For large systems, multi-thread programming is ubiquitous along with asynchronous programming, such as event routing. This presentation focuses on dealing with threads and callbacks while embedding Python in other applications.
This document provides an overview of Objective-C and discusses several key concepts:
1. It begins with instructions for setting up the Objective-C development environment on Linux, Mac OS X, and Windows systems.
2. A "Hello World" example program is presented to demonstrate the basic structure of an Objective-C application and how to print output.
3. Object-oriented concepts like classes, inheritance, and polymorphism are explained through examples showing how to define classes with interfaces and implementations, create class instances, and call methods.
4. Additional Objective-C features are demonstrated like method parameters, constructors, access privileges, class methods, and exceptions handling.
C Programming Language Tutorial for beginners - JavaTpointJavaTpoint.Com
JavaTpoint share a presentation of C Programming language for beginners and professionals. now in this slideshare you will be learned basics of c programming language, what is c programming language, history of c programming, installing turbo c, features of c programming language, datatypes of c language, operaters in c, control statement of c language, c language functions, c array, pointer in c programming, and structure and union.
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...David Beazley (Dabeaz LLC)
The document describes an embedded error recovery and debugging mechanism for scripting language extensions. It discusses how errors can occur both in script code and extension code built as shared libraries. Debugging errors in extension code is challenging as typical debuggers and tracebacks do not work. The document then presents the Wrapped Application Debugger (WAD) which allows debugging of extension code as if it were part of the script by capturing signals and integrating with the GNU Debugger (GDB).
This document provides an overview of the C programming language development process. It discusses the different phases a C program goes through from editing the source code to execution. It describes the preprocessor, compiler, linker, and loader and their roles. It also covers C program structures like comments, header files, and the main function. Finally, it discusses some C fundamentals like data types, variables, literals, and variable scope.
PHPcon Poland - Static Analysis of PHP Code – How the Heck did I write so man...Rouven Weßling
Static analysis tools can analyze code without executing it to find bugs and issues. The document discusses several static analysis tools for PHP like PHPMD, Phan, PHPCS, PHPLOC, Deptrac. It explains what they do, like PHPLOC gathering complexity metrics and Deptrac checking for violations of defined layer dependencies. In the end, it recommends using static analysis in CI and not trusting results blindly without understanding the underlying errors.
This document provides an overview of key concepts in C programming including identifiers, keywords, data types, operators, control statements, and functions for controlling program flow. It discusses identifiers and keywords rules. It also covers basic data types and different operators used in C. The document explains various control statements like if-else, switch case, for, while, do-while loops. It provides examples of using conditional operators and break and continue statements. Finally, it discusses nested loops and references additional resources to learn C programming.
What is the Joomla Framework and why do we need it?Rouven Weßling
The new Joomla Framework was met with both skepticism and excitement in the community. What is the difference between the Platform and the Framework? Why is it a good idea? And how does this open us up to the wider PHP community? We'd like to give you some answers.
PascalScript is a scripting engine that allows scripts written in Object Pascal to be executed at runtime in Delphi and Free Pascal applications. It provides advantages like allowing customization without recompiling and updating applications by distributing new script files. The engine works by compiling scripts to bytecode using a compiler component, and executing the bytecode using an executer component. It supports common data types, functions, classes, and calling external libraries.
Python is a great language, but there are occasions where we need access to low level operations or connect with some database driver written in C. With the FFI(Foreign function interface) we can connect Python with other languages like C, C++ and even the new Rust. There are some alternatives to achieve this goal, Native Extensions, Ctypes and CFFI. I'll compare this three ways of extending Python.
SWIG (Simplified Wrapper and Interface Generator) is a tool that connects programs written in C/C++ with scripting languages like Perl, Python, Ruby and Tcl. It works by reading interface definition files that describe functions and variables in a C/C++ library and generating wrapper code that allows these functions and variables to be accessed from a scripting language. SWIG handles much of the complexity of interfacing C/C++ code with other languages. It allows prototyping and debugging integration between different systems and simplifies building extension modules for languages like Perl.
C Programming Language Step by Step Part 1Rumman Ansari
This document provides an overview of the C programming language. It discusses the history and development of C, starting with predecessors like ALGOL-60 and BCPL in the 1960s and 1970s. C was created in the early 1970s and the first C compiler was released in 1978. Since then, C has become widely used for system programming and is foundational to many other languages like C++ and Java. The document outlines some key advantages of C, like its efficiency and ability to handle low-level tasks. It also provides brief descriptions of common C programming concepts.
Hack is a programming language designed for the HHVM runtime. HHVM compiles PHP and Hack code into an intermediate bytecode which is then JIT compiled to machine code, providing better performance than traditional PHP execution. Some key features of Hack include gradual typing, generics, and async functions. Hack brings together popular features from PHP, C#, and Java. Facebook uses HHVM and Hack to realize a 9x increase in request throughput and 5x reduction in memory usage compared to traditional PHP.
1. The document discusses different ways of creating custom data types in C++, including classes, structures, unions, enumerations, and typedef. Structures are collections of variables that can be referenced under one name.
2. Technically, there is no difference between a structure and a class in C++ - structures are classes with members that are public by default, while classes have private members by default.
3. Structures allow logically related elements to be treated as a single unit, for example to store student information. Arrays can contain elements of a structure type.
This document provides an overview of key differences between C and C++. It discusses how C++ was designed to be compatible with C but adds features like classes, templates, and exceptions. It notes some common C constructs like function prototypes, printf/scanf, arrays, strings, memory management with malloc/free, macros, and const that have equivalents but sometimes subtle differences in C++. The document aims to help C++ programmers understand how to program in C when needed.
This document discusses debugging techniques for C programs. It defines debugging as finding why a program does not work as expected after compiling without errors. Key techniques include annotating code with print statements to check execution paths and variable values, using compiler flags to enable warnings, reading error messages carefully, taking breaks when stuck, and using a debugger to view stack traces if a program crashes. Common errors like missing breaks, incorrect operator usage, and pointer issues are also outlined.
The document discusses how the Java Virtual Machine (JVM) supports dynamic languages through the invokedynamic bytecode instruction. This simplifies the implementation of compilers and runtime systems for dynamically typed languages on the JVM by allowing method dispatch to be deferred until runtime. It also describes how method handles in Java 7 provide a more efficient and flexible way to access methods compared to reflection by embedding access restrictions and allowing faster invocation and combination of methods.
This document summarizes a presentation given on why to choose Hack/HHVM over PHP7. Some key points made include:
1. Hack provides more powerful type hinting capabilities compared to PHP7, including support for nullable and mixed types.
2. Hack features original collections like Vector, Map, Set and Pair that allow specifying value types, unlike PHP arrays.
3. Hack has original language specifications like lambdas, generics, and enums not in PHP7.
4. Hack allows parallel execution out of the box for higher performance.
5. Hack's static analysis tool catches errors before runtime for more bug-free code.
6. HHVM continues to incorporate features from PHP
HHVM is a virtual machine developed by Facebook that executes PHP and Hack code faster than traditional PHP interpreters. It began as a just-in-time compiler for PHP (HipHop) and has evolved to include a bytecode interpreter and support for the Hack programming language. HHVM can be used as a drop-in replacement for PHP and supports many PHP extensions and features while offering performance improvements of up to 2x over PHP. It additionally provides static typing and type checking via the Hack language to improve code quality.
An introduction to the C programming language for the students of the course "HJ-82 Ontwerpen voor de optie multimedia en signaalverwerking: seminaries", taught by the authors at the Catholic University of Leuven.
C is a programming language developed in 1972 by Dennis Ritchie at Bell Labs. It is a structured programming language that is highly portable and supports functions. A C program consists of functions, with a main function that is the program entry point. Input/output in C uses predefined functions like printf() and scanf(). A C program is compiled into an executable file that can run on many machine architectures. The document then discusses C program structure, data types, libraries, variables, keywords, operators, and control flow statements like if/else, switch, while, do-while and for loops.
Threads and Callbacks for Embedded PythonYi-Lung Tsai
Python is a great choice to be customized plug-ins for existing applications. Extending existing applications with Python program is also practical. For large systems, multi-thread programming is ubiquitous along with asynchronous programming, such as event routing. This presentation focuses on dealing with threads and callbacks while embedding Python in other applications.
This document provides an overview of Objective-C and discusses several key concepts:
1. It begins with instructions for setting up the Objective-C development environment on Linux, Mac OS X, and Windows systems.
2. A "Hello World" example program is presented to demonstrate the basic structure of an Objective-C application and how to print output.
3. Object-oriented concepts like classes, inheritance, and polymorphism are explained through examples showing how to define classes with interfaces and implementations, create class instances, and call methods.
4. Additional Objective-C features are demonstrated like method parameters, constructors, access privileges, class methods, and exceptions handling.
C Programming Language Tutorial for beginners - JavaTpointJavaTpoint.Com
JavaTpoint share a presentation of C Programming language for beginners and professionals. now in this slideshare you will be learned basics of c programming language, what is c programming language, history of c programming, installing turbo c, features of c programming language, datatypes of c language, operaters in c, control statement of c language, c language functions, c array, pointer in c programming, and structure and union.
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...David Beazley (Dabeaz LLC)
The document describes an embedded error recovery and debugging mechanism for scripting language extensions. It discusses how errors can occur both in script code and extension code built as shared libraries. Debugging errors in extension code is challenging as typical debuggers and tracebacks do not work. The document then presents the Wrapped Application Debugger (WAD) which allows debugging of extension code as if it were part of the script by capturing signals and integrating with the GNU Debugger (GDB).
This document provides an overview of the C programming language development process. It discusses the different phases a C program goes through from editing the source code to execution. It describes the preprocessor, compiler, linker, and loader and their roles. It also covers C program structures like comments, header files, and the main function. Finally, it discusses some C fundamentals like data types, variables, literals, and variable scope.
PHPcon Poland - Static Analysis of PHP Code – How the Heck did I write so man...Rouven Weßling
Static analysis tools can analyze code without executing it to find bugs and issues. The document discusses several static analysis tools for PHP like PHPMD, Phan, PHPCS, PHPLOC, Deptrac. It explains what they do, like PHPLOC gathering complexity metrics and Deptrac checking for violations of defined layer dependencies. In the end, it recommends using static analysis in CI and not trusting results blindly without understanding the underlying errors.
This document provides an overview of key concepts in C programming including identifiers, keywords, data types, operators, control statements, and functions for controlling program flow. It discusses identifiers and keywords rules. It also covers basic data types and different operators used in C. The document explains various control statements like if-else, switch case, for, while, do-while loops. It provides examples of using conditional operators and break and continue statements. Finally, it discusses nested loops and references additional resources to learn C programming.
What is the Joomla Framework and why do we need it?Rouven Weßling
The new Joomla Framework was met with both skepticism and excitement in the community. What is the difference between the Platform and the Framework? Why is it a good idea? And how does this open us up to the wider PHP community? We'd like to give you some answers.
PascalScript is a scripting engine that allows scripts written in Object Pascal to be executed at runtime in Delphi and Free Pascal applications. It provides advantages like allowing customization without recompiling and updating applications by distributing new script files. The engine works by compiling scripts to bytecode using a compiler component, and executing the bytecode using an executer component. It supports common data types, functions, classes, and calling external libraries.
Python is a great language, but there are occasions where we need access to low level operations or connect with some database driver written in C. With the FFI(Foreign function interface) we can connect Python with other languages like C, C++ and even the new Rust. There are some alternatives to achieve this goal, Native Extensions, Ctypes and CFFI. I'll compare this three ways of extending Python.
SWIG (Simplified Wrapper and Interface Generator) is a tool that connects programs written in C/C++ with scripting languages like Perl, Python, Ruby and Tcl. It works by reading interface definition files that describe functions and variables in a C/C++ library and generating wrapper code that allows these functions and variables to be accessed from a scripting language. SWIG handles much of the complexity of interfacing C/C++ code with other languages. It allows prototyping and debugging integration between different systems and simplifies building extension modules for languages like Perl.
C Programming Language Step by Step Part 1Rumman Ansari
This document provides an overview of the C programming language. It discusses the history and development of C, starting with predecessors like ALGOL-60 and BCPL in the 1960s and 1970s. C was created in the early 1970s and the first C compiler was released in 1978. Since then, C has become widely used for system programming and is foundational to many other languages like C++ and Java. The document outlines some key advantages of C, like its efficiency and ability to handle low-level tasks. It also provides brief descriptions of common C programming concepts.
Hack is a programming language designed for the HHVM runtime. HHVM compiles PHP and Hack code into an intermediate bytecode which is then JIT compiled to machine code, providing better performance than traditional PHP execution. Some key features of Hack include gradual typing, generics, and async functions. Hack brings together popular features from PHP, C#, and Java. Facebook uses HHVM and Hack to realize a 9x increase in request throughput and 5x reduction in memory usage compared to traditional PHP.
1. The document discusses different ways of creating custom data types in C++, including classes, structures, unions, enumerations, and typedef. Structures are collections of variables that can be referenced under one name.
2. Technically, there is no difference between a structure and a class in C++ - structures are classes with members that are public by default, while classes have private members by default.
3. Structures allow logically related elements to be treated as a single unit, for example to store student information. Arrays can contain elements of a structure type.
This document provides an overview of key differences between C and C++. It discusses how C++ was designed to be compatible with C but adds features like classes, templates, and exceptions. It notes some common C constructs like function prototypes, printf/scanf, arrays, strings, memory management with malloc/free, macros, and const that have equivalents but sometimes subtle differences in C++. The document aims to help C++ programmers understand how to program in C when needed.
The document discusses new approaches to teaching English in India. It advocates moving away from conventional grammar-based and rote learning methods towards more activity-oriented and self-learning approaches. The national curriculum framework recommends linking learning to students' lives outside school to reduce the gap between school, home, and community. It also discourages strictly separating subject areas. The document discusses constructing knowledge through interaction and experience. It outlines the four skills of language learning - listening, speaking, reading, and writing - and provides examples of activities to develop each skill. It advocates continuous and comprehensive evaluation over high-stakes exams to improve the teaching-learning process.
The document provides guidance on writing formal and informal letters. It discusses objectives like teaching letter format, etiquette, and strategies. Letters can be sent electronically, by hand, or mail. Etiquette is about promoting civility. Letters should be read carefully before responding and the tone should match what is being responded to. Letters reflect the writer's character and skill. Active voice and specificity are recommended over passive voice and vagueness. Thank you, apology, and invitation letters follow guidelines for being sincere, brief, and addressing a specific situation.
An introduction to KOER December 2013 KarnatakaOER
This document discusses the Karnataka Open Educational Resources (KOER) initiative, a new model of teacher education. KOER aims to create a community of teachers who collaboratively develop, share, and review open educational resources using a wiki platform. It allows teachers to play a key role in creating locally relevant and dynamic learning materials. By participating in the creation of these resources, teachers engage in peer-learning and continuous professional development. The initiative has seen over 100 teachers create over 2000 resource pages and files on subjects like math, science, and social studies. It is helping move beyond a solely textbook-based approach in Karnataka classrooms.
Study: The Future of VR, AR and Self-Driving CarsLinkedIn
We asked LinkedIn members worldwide about their levels of interest in the latest wave of technology: whether they’re using wearables, and whether they intend to buy self-driving cars and VR headsets as they become available. We asked them too about their attitudes to technology and to the growing role of Artificial Intelligence (AI) in the devices that they use. The answers were fascinating – and in many cases, surprising.
This SlideShare explores the full results of this study, including detailed market-by-market breakdowns of intention levels for each technology – and how attitudes change with age, location and seniority level. If you’re marketing a tech brand – or planning to use VR and wearables to reach a professional audience – then these are insights you won’t want to miss.
Artificial intelligence (AI) is everywhere, promising self-driving cars, medical breakthroughs, and new ways of working. But how do you separate hype from reality? How can your company apply AI to solve real business problems?
Here’s what AI learnings your business should keep in mind for 2017.
The document provides an introduction to the C programming language, including its history and evolution. It discusses key elements of C programs like main functions, libraries, headers, source/header files. It also covers basic C concepts like data types, variables, operators, functions, pointers, arrays, comments and preprocessor directives. Examples of simple C programs are provided to illustrate these concepts.
The document provides an introduction to the C programming language, including its history and evolution. It discusses key elements of C programs like functions, variables, data types, comments, preprocessor directives, libraries and headers. It also covers pointers, arrays, passing command line arguments and standard header files in C. Examples of simple C programs are provided to illustrate various concepts.
The document provides an introduction to the C programming language, including its history and evolution. It discusses key elements of C programs like functions, variables, data types, libraries, headers, and compilers. It also covers pointers, arrays, preprocessor directives, and macros. Examples are provided to illustrate basic C programs and common programming constructs in C.
This document outlines the basics of C++ programming, including:
- The history and evolution of C++ and other programming languages.
- How a C++ source code is compiled into an executable program by the compiler in multiple steps like preprocessing, compiling, linking etc.
- The structure of a basic C++ program and key elements like main function, headers, comments.
- How to use input/output streams, variables, arithmetic operations, and conditional statements like if-else in a C++ program.
C is a procedural programming language. It was developed in the early 1970s and is still widely used. The document provides an overview of key aspects of C including data types, variables, constants, operators, control statements like if/else, and functions. It also discusses C programming concepts like low-level vs high-level languages, header files, comments, escape sequences, and more. The document serves as a useful introduction and reference for someone learning the basics of the C programming language.
This document provides an overview of the basic structure and components of a C++ program. It summarizes:
- The main() function is the starting point of execution for a C++ program and contains the program logic.
- Preprocessor directives like #include are used to incorporate header files containing declarations needed by the program.
- The using namespace std directive allows the program to access standard library components like cout without specifying the std namespace.
- The cout object outputs text to the screen via the insertion operator <<.
This document provides an introduction to the C programming language. It discusses key concepts like functions, variables, data types, memory, scopes, expressions, operators, control flow with if/else statements and loops. It also explains how passing arguments by value means functions cannot directly modify their parameters, but passing addresses allows modifying variables in the calling scope. Overall it serves as a helpful primer on basic C syntax and programming concepts for newcomers to the language.
This document provides an overview of basic C++ programming concepts including:
1) Preprocessor directives like #include are used to include standard header files like iostream. Header files contain pre-defined functions.
2) The main() function is where program execution begins. Statements written within the curly braces of main() comprise the program body.
3) Output is displayed using the cout stream object and insertion operator <<. Common output commands print text to the standard output on the monitor.
This document provides an overview of the C programming language under Linux, covering preprocessing, compiling, assembling, linking, libraries, and related tools. It discusses:
1. The four main steps of preprocessing, compiling, assembling, and linking using GNU tools like cpp, cc1, as, and collect2.
2. How to display symbol tables using nm and strip symbols from executables.
3. Creating static libraries with ar and ranlib and linking them, as well as creating shared libraries with gcc and soname.
4. The roles of environment variables like LIBRARY_PATH and LD_LIBRARY_PATH in locating libraries.
C is a procedural programming language developed in the late 1960s and early 1970s. It was designed for system programming tasks like operating system and compiler development. Many later languages took syntax and features from C. The structure of a C program includes header file inclusions, a main function declaration, variable declarations, program logic in the body, and a return statement. A simple "Hello World" program is presented as an example to demonstrate the basic structure of a C program.
C is mother language of all programming language.
It is a system programming language. It is a procedure-oriented programming language. It is also called mid-level programming language.
C evolved from a language called B, written by Ken Thompson at Bell Labs in 1970. Ken used B to write one of the first implementations of UNIX. B in turn was a descendant of the language BCPL (developed at Cambridge (UK) in 1967), with most of its instructions removed.
So many instructions were removed in going from BCPL to B, that Dennis Ritchie of Bell Labs put some back in (in 1972), and called the language C.
The famous book The C Programming Language was written by Kernighan and Ritchie in 1978, and was the definitive reference book on C for almost a decade.
The original C was still too limiting, and not standardized, and so in 1983, an ANSI committee was established to formalize the language definition.
It has taken until now (ten years later) for the ANSI ( American National Standard Institute) standard to become well accepted and almost universally supported by compilers.
The document discusses key concepts in the C programming language including its popularity due to being robust, efficient, fast, and portable. It describes C's character set including alphabets, digits, and special symbols that can be used to form constants, variables, and keywords. Constants represent values that do not change, while variables represent unknown values. Keywords are reserved words in C that are predefined like int, long, struct, etc. The document also discusses the structure of a C program including comments, preprocessor directives, declarations, functions, and executable statements. It provides an example of a simple "Hello World" C program to print that message.
1 CMPS 12M Introduction to Data Structures Lab La.docxtarifarmarie
1
CMPS 12M
Introduction to Data Structures Lab
Lab Assignment 3
The purpose of this lab assignment is to introduce the C programming language, including standard input-output
functions, command line arguments, File IO, and compilation with Makefiles.
Introduction to C
If you are not already familiar with C (or even if you are) it is recommended that you purchase a good C reference
such as C for Java Programmers: a Primer by Charlie McDowell (Lulu.com 2007). The C programming
language is, in a certain sense, the grandparent of Java (C++ being its parent). Java is known as an Object Oriented
Programming (OOP) language, which means that data structures and the procedures which operate on them are
grouped together into one language construct, namely the class. Common behavior amongst classes is specified
explicitly through the mechanism of inheritance. The C programming language on the other hand does not
directly support OOP, although it can be implemented with some effort. C is known as a procedural programming
language, which means that data structures and functions (i.e. procedures) are separate language constructs. There
are no classes, no objects, and no inheritance. New data types in C are created using the typedef and struct
constructs, which will be illustrated in future lab assignments. There is however much common syntax between
Java and C. Many control structures such as loops (while, do-while, for), and branching (if, if-else, switch) are
virtually identical in the two languages. One major difference is in the way program input and output is handled,
both to and from standard IO devices (keyboard and terminal window), and to and from files. The following is
an example of a "Hello World!" program in C.
Example
/*
* hello.c
* Prints "Hello World!" to stdout
*/
#include <stdio.h>
int main(){
printf("Hello World!\n");
return 0;
}
Comments in C are specified by bracketing them between the strings /* and */, and may span several lines. For
instance /* comment */ or
/* comment
comment */
or
/*
* comment
* comment
*/
are all acceptable. With the right compiler flags, Java/C++ style comments are also acceptable.
// comment
// comment
2
You may use any style you like, but throughout this document we will use the older C style /*comments*/.
Any line beginning with # is known as a preprocessor directive. The preprocessor performs the first phase of
compilation wherein these directives, which are literal text substitutions, are performed, making the program
ready for later stages of compilation. The line #include<stdio.h> inserts the standard library header file
stdio.h, which specifies functions for performing standard input-output operations. Notice that preprocessor
commands in C do not end in a semicolon. One can also specify constant macros using the #define preprocessor
directive as follows.
.
The document discusses the basic structure of C programs. It explains that a C program contains functions that are organized into different sections, including a documentation section, link section, definition section, main function section, and optional subprogram section. It provides details on what each section is used for and example code to demonstrate the main components of a C program, including functions, variables, data types, and memory organization.
The document discusses the basic structure of C programs. It explains that a C program contains functions that are organized into different sections, including a documentation section, link section, definition section, main function section, and optional subprogram section. It provides details on what each section is used for and example code to demonstrate the main components of a C program, including functions, variables, data types, and memory organization.
The main function serves as the starting point for program execution. It controls program flow by calling other functions. A program typically ends at the end of main. All C programs must have a main function which takes no arguments and returns an int. Main contains the core logic that runs the program. Preprocessor directives like #include add functionality by including header files. Macros defined with #define are text replacements that occur before compilation. Conditional compilation with #ifdef/#ifndef includes or excludes blocks of code based on symbol definitions.
C++ was created by Bjarne Stroustrup in 1979 at Bell Labs as an enhancement to the C language. It combines procedural and object-oriented programming. A C++ program consists of functions, the basic unit of which is main(). Functions can be library functions or user-defined and are made up of prototypes, definitions, and calls. The program also uses various data types and variables like local and global.
C is a general-purpose programming language widely used to develop operating systems and compilers. It was developed in the early 1970s at Bell Labs by Dennis Ritchie. Some key reasons for C's popularity include its efficiency, ability to access low-level hardware, and ability to be compiled on a variety of computers. C source code files use a .c extension and must be compiled into an executable binary file before running. Common uses of C include operating systems, language compilers, databases, and network drivers.
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...SOFTTECHHUB
The choice of an operating system plays a pivotal role in shaping our computing experience. For decades, Microsoft's Windows has dominated the market, offering a familiar and widely adopted platform for personal and professional use. However, as technological advancements continue to push the boundaries of innovation, alternative operating systems have emerged, challenging the status quo and offering users a fresh perspective on computing.
One such alternative that has garnered significant attention and acclaim is Nitrux Linux 3.5.0, a sleek, powerful, and user-friendly Linux distribution that promises to redefine the way we interact with our devices. With its focus on performance, security, and customization, Nitrux Linux presents a compelling case for those seeking to break free from the constraints of proprietary software and embrace the freedom and flexibility of open-source computing.
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc
How does your privacy program stack up against your peers? What challenges are privacy teams tackling and prioritizing in 2024?
In the fifth annual Global Privacy Benchmarks Survey, we asked over 1,800 global privacy professionals and business executives to share their perspectives on the current state of privacy inside and outside of their organizations. This year’s report focused on emerging areas of importance for privacy and compliance professionals, including considerations and implications of Artificial Intelligence (AI) technologies, building brand trust, and different approaches for achieving higher privacy competence scores.
See how organizational priorities and strategic approaches to data security and privacy are evolving around the globe.
This webinar will review:
- The top 10 privacy insights from the fifth annual Global Privacy Benchmarks Survey
- The top challenges for privacy leaders, practitioners, and organizations in 2024
- Key themes to consider in developing and maintaining your privacy program
A tale of scale & speed: How the US Navy is enabling software delivery from l...sonjaschweigert1
Rapid and secure feature delivery is a goal across every application team and every branch of the DoD. The Navy’s DevSecOps platform, Party Barge, has achieved:
- Reduction in onboarding time from 5 weeks to 1 day
- Improved developer experience and productivity through actionable findings and reduction of false positives
- Maintenance of superior security standards and inherent policy enforcement with Authorization to Operate (ATO)
Development teams can ship efficiently and ensure applications are cyber ready for Navy Authorizing Officials (AOs). In this webinar, Sigma Defense and Anchore will give attendees a look behind the scenes and demo secure pipeline automation and security artifacts that speed up application ATO and time to production.
We will cover:
- How to remove silos in DevSecOps
- How to build efficient development pipeline roles and component templates
- How to deliver security artifacts that matter for ATO’s (SBOMs, vulnerability reports, and policy evidence)
- How to streamline operations with automated policy checks on container images
Climate Impact of Software Testing at Nordic Testing DaysKari Kakkonen
My slides at Nordic Testing Days 6.6.2024
Climate impact / sustainability of software testing discussed on the talk. ICT and testing must carry their part of global responsibility to help with the climat warming. We can minimize the carbon footprint but we can also have a carbon handprint, a positive impact on the climate. Quality characteristics can be added with sustainability, and then measured continuously. Test environments can be used less, and in smaller scale and on demand. Test techniques can be used in optimizing or minimizing number of tests. Test automation can be used to speed up testing.
Securing your Kubernetes cluster_ a step-by-step guide to success !KatiaHIMEUR1
Today, after several years of existence, an extremely active community and an ultra-dynamic ecosystem, Kubernetes has established itself as the de facto standard in container orchestration. Thanks to a wide range of managed services, it has never been so easy to set up a ready-to-use Kubernetes cluster.
However, this ease of use means that the subject of security in Kubernetes is often left for later, or even neglected. This exposes companies to significant risks.
In this talk, I'll show you step-by-step how to secure your Kubernetes cluster for greater peace of mind and reliability.
Threats to mobile devices are more prevalent and increasing in scope and complexity. Users of mobile devices desire to take full advantage of the features
available on those devices, but many of the features provide convenience and capability but sacrifice security. This best practices guide outlines steps the users can take to better protect personal devices and information.
For the full video of this presentation, please visit: https://www.edge-ai-vision.com/2024/06/building-and-scaling-ai-applications-with-the-nx-ai-manager-a-presentation-from-network-optix/
Robin van Emden, Senior Director of Data Science at Network Optix, presents the “Building and Scaling AI Applications with the Nx AI Manager,” tutorial at the May 2024 Embedded Vision Summit.
In this presentation, van Emden covers the basics of scaling edge AI solutions using the Nx tool kit. He emphasizes the process of developing AI models and deploying them globally. He also showcases the conversion of AI models and the creation of effective edge AI pipelines, with a focus on pre-processing, model conversion, selecting the appropriate inference engine for the target hardware and post-processing.
van Emden shows how Nx can simplify the developer’s life and facilitate a rapid transition from concept to production-ready applications.He provides valuable insights into developing scalable and efficient edge AI solutions, with a strong focus on practical implementation.
“An Outlook of the Ongoing and Future Relationship between Blockchain Technologies and Process-aware Information Systems.” Invited talk at the joint workshop on Blockchain for Information Systems (BC4IS) and Blockchain for Trusted Data Sharing (B4TDS), co-located with with the 36th International Conference on Advanced Information Systems Engineering (CAiSE), 3 June 2024, Limassol, Cyprus.
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slackshyamraj55
Discover the seamless integration of RPA (Robotic Process Automation), COMPOSER, and APM with AWS IDP enhanced with Slack notifications. Explore how these technologies converge to streamline workflows, optimize performance, and ensure secure access, all while leveraging the power of AWS IDP and real-time communication via Slack notifications.
Removing Uninteresting Bytes in Software FuzzingAftab Hussain
Imagine a world where software fuzzing, the process of mutating bytes in test seeds to uncover hidden and erroneous program behaviors, becomes faster and more effective. A lot depends on the initial seeds, which can significantly dictate the trajectory of a fuzzing campaign, particularly in terms of how long it takes to uncover interesting behaviour in your code. We introduce DIAR, a technique designed to speedup fuzzing campaigns by pinpointing and eliminating those uninteresting bytes in the seeds. Picture this: instead of wasting valuable resources on meaningless mutations in large, bloated seeds, DIAR removes the unnecessary bytes, streamlining the entire process.
In this work, we equipped AFL, a popular fuzzer, with DIAR and examined two critical Linux libraries -- Libxml's xmllint, a tool for parsing xml documents, and Binutil's readelf, an essential debugging and security analysis command-line tool used to display detailed information about ELF (Executable and Linkable Format). Our preliminary results show that AFL+DIAR does not only discover new paths more quickly but also achieves higher coverage overall. This work thus showcases how starting with lean and optimized seeds can lead to faster, more comprehensive fuzzing campaigns -- and DIAR helps you find such seeds.
- These are slides of the talk given at IEEE International Conference on Software Testing Verification and Validation Workshop, ICSTW 2022.
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!SOFTTECHHUB
As the digital landscape continually evolves, operating systems play a critical role in shaping user experiences and productivity. The launch of Nitrux Linux 3.5.0 marks a significant milestone, offering a robust alternative to traditional systems such as Windows 11. This article delves into the essence of Nitrux Linux 3.5.0, exploring its unique features, advantages, and how it stands as a compelling choice for both casual users and tech enthusiasts.
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...Zilliz
Join us to introduce Milvus Lite, a vector database that can run on notebooks and laptops, share the same API with Milvus, and integrate with every popular GenAI framework. This webinar is perfect for developers seeking easy-to-use, well-integrated vector databases for their GenAI apps.
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...Neo4j
Leonard Jayamohan, Partner & Generative AI Lead, Deloitte
This keynote will reveal how Deloitte leverages Neo4j’s graph power for groundbreaking digital twin solutions, achieving a staggering 100x performance boost. Discover the essential role knowledge graphs play in successful generative AI implementations. Plus, get an exclusive look at an innovative Neo4j + Generative AI solution Deloitte is developing in-house.
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
C tutorial
1. A Quick Introduction to C Programming
Lewis Girod
CENS Systems Lab
July 5, 2005
http://lecs.cs.ucla.edu/~girod/talks/c-tutorial.ppt
1
2. or,
What I wish I had known about C
during my first summer internship
With extra info in
the NOTES
2
3. High Level Question: Why is Software Hard?
Answer(s):
• Complexity: Every conditional (“if”) doubles number of paths
through your code, every bit of state doubles possible states
– Solution: reuse code with functions, avoid duplicate state variables
• Mutability: Software is easy to change.. Great for rapid fixes ..
And rapid breakage .. always one character away from a bug
– Solution: tidy, readable code, easy to understand by inspection.
Avoid code duplication; physically the same logically the same
• Flexibility: Programming problems can be solved in many
different ways. Few hard constraints plenty of “rope”.
– Solution: discipline and idioms; don’t use all the rope
3
4. Writing and Running Programs
#include <stdio.h>
/* The simplest C Program */
int main(int argc, char
**argv)
1. Write text of program (source code) using an editor
{
printf(“Hello Worldn”);
such as emacs, save as file e.g. my_program.c
return 0;
}
2. Run the compiler to convert program from source to
an “executable” or “binary”:
$ gcc –Wall –g my_program.c –o my_program
$ gcc -Wall –g my_program.c –o my_program
tt.c: In function `main':
-Wall –g ?
tt.c:6: parse error before `x'
tt.c:5: parm types given both in parmlist and
separately
tt.c:8: `x' undeclared (first use in this function)
3-N. Compiler gives errors and warnings; edit source
tt.c:8: (Each undeclared identifier is reported only
once file, fix it, and re-compile
tt.c:8: for each function it appears in.)
tt.c:10: warning: control reaches end of non-void
function
tt.c: At top level:
N. Run it and see if it works
tt.c:11: parse error before `return'
./?
$ ./my_program
my_program Hello World
What if it doesn’t work?
$▌
4
5. C Syntax and Hello World
#include inserts another file. “.h” files are called
“header” files. They contain stuff needed to interface to
libraries and code in other “.c” files. Can your program have
What do the < > more than one .c file?
mean?
This is a comment. The compiler ignores this.
#include <stdio.h> The main() function is always
/* The simplest C Program */ where your program starts
int main(int argc, char **argv) running.
{
Blocks of code (“lexical
printf(“Hello Worldn”); scopes”) are marked by { … }
return 0;
}
Return ‘0’ from this function Print out a message. ‘n’ means “new line”.
5
6. A Quick Digression About the Compiler
#include <stdio.h>
/* The simplest C Program */
int main(int argc, char
Preprocess Compilation occurs in two steps:
**argv)
{ “Preprocessing” and “Compiling”
printf(“Hello Worldn”);
return 0; Why ?
}
__extension__ typedef unsigned long long int In Preprocessing, source code is “expanded” into a
__dev_t;
__extension__ typedef unsigned int __uid_t; larger form that is simpler for the compiler to
understand. Any line that starts with ‘#’ is a line
__extension__ typedef unsigned int __gid_t;
__extension__ typedef unsigned long int __ino_t;
that is interpreted by the Preprocessor.
__extension__ typedef unsigned long long int
__ino64_t;
__extension__ typedef unsigned int __nlink_t;
__extension__ typedef long int __off_t;
__extension__ typedef long long int __off64_t;
extern void flockfile (FILE *__stream)
extern int ftrylockfile (FILE *__stream)
;
;
• Include files are “pasted in” (#include)
extern void funlockfile (FILE *__stream)
int main(int argc, char **argv)
; • Macros are “expanded” (#define)
{
printf(“Hello Worldn”);
• Comments are stripped out ( /* */ , // )
return 0; • Continued lines are joined ( )
}
?
my_program The compiler then converts the resulting text into
Compile
binary code the CPU can run directly.
6
7. OK, We’re Back.. What is a Function?
A Function is a series of instructions to run. You
pass Arguments to a function and it returns a Value.
“main()” is a Function. It’s only special because it
always gets called first when you run your program.
Return type, or void
Function Arguments
#include <stdio.h>
/* The simplest C Program */
int main(int argc, char **argv)
{ Calling a Function: “printf()” is just
another function, like main(). It’s defined
printf(“Hello Worldn”); for you in a “library”, a collection of
return 0; functions you can call from your program.
}
Returning a value
7
8. What is “Memory”?
Memory is like a big table of numbered Addr Value
slots where bytes can be stored. 0
1
The number of a slot is its Address. 2
One byte Value can be stored in each slot. 3
72?
4 ‘H’ (72)
Some “logical” data values span more than 5 ‘e’ (101)
one slot, like the character string “Hellon”
6 ‘l’ (108)
A Type names a logical meaning to a span 7 ‘l’ (108)
of memory. Some simple types are: 8 ‘o’ (111)
a single character (1 slot) 9 ‘n’ (10)
char
char an array of 10 characters 10 ‘0’ (0)
[10] signed 4 byte integer 11
not always…
int 4 byte floating point
float signed 8 byte integer 12
Signed?…
int64_t
8
9. What is a Variable?
symbol table?
A Variable names a place in memory where Symbol Addr Value
you store a Value of a certain Type. 0
1
You first Define a variable by giving it a 2
name and specifying the type, and 3
optionally an initial value declare vs define? x 4 ?
y 5 ‘e’ (101)
char x; Initial value of x is undefined
char y=‘e’; 6
7
The compiler puts them
Initial value 8
somewhere in memory.
9
Name What names are legal? 10
11
Type is single character (char)
12
extern? static? const?
9
10. Multi-byte Variables
Different types consume different amounts Symbol Addr Value
of memory. Most architectures store data 0
on “word boundaries”, or even multiples of 1
the size of a primitive data type (int, char) 2
3
char x;
char y=‘e’; x 4 ?
int z = y 5 ‘e’ (101)
0x01020304;
6
0x means the constant is padding
written in hex 7
z 8 4
9 3
An int consumes 4 bytes
10 2
11 1
12
10
11. Lexical Scoping (Returns nothing)
void p(char x)
Every Variable is Defined within some scope. {
A Variable cannot be referenced by name char y;
/* p,x */
(a.k.a. Symbol) from outside of that scope. /* p,x,y */
char z;
/* p,x,y,z */
}
Lexical scopes are defined with curly braces { }. /* p */
char z;
/* p,z */
The scope of Function Arguments is the
void q(char a)
complete body of the function. {
char b;
/* p,z,q,a,b
The scope of Variables defined inside a */
char b?
function starts at the definition and ends at {
the closing brace of the containing block char c;
/* p,z,q,a,b,c
*/
legal?
}
The scope of Variables defined outside a
function starts at the definition and ends at char d;
/* p,z,q,a,b,d (not c)
the end of the file. Called “Global” Vars. */
}
/* p,z,q */
11
12. Expressions and Evaluation
Expressions combine Values using Operators, according to precedence.
1 + 2 * 2 1 + 4 5
(1 + 2) * 2 3 * 2 6
Symbols are evaluated to their Values before being combined.
int x=1;
int y=2;
x + y * y x + 2 * 2 x + 4 1 + 4
5
Comparison operators are used to compare values.
In C, 0 means “false”, and any other value means “true”.
int x=4;
(x < 5) (4 < 5) <true>
(x < 4) (4 < 4) 0
((x < 5) || (x < 4)) (<true> || (x < 4)) <true>
Not evaluated because
first clause was true
12
13. Comparison and Mathematical Operators
== equal to The rules of precedence are clearly
< less than defined but often difficult to remember
<= less than or equal
> greater than or non-intuitive. When in doubt, add
>= greater than or equal parentheses to make it explicit. For
!= not equal
&& logical and
oft-confused cases, the compiler will
|| logical or give you a warning “Suggest parens
! logical not around …” – do it!
+ plus & bitwise
- minus and Beware division:
* mult | bitwise or • If second argument is integer, the
/ ^ bitwise
divide xor result will be integer (rounded):
% ~ bitwise 5 / 10 0 whereas 5 / 10.0 0.5
modulo not
<< shift left
• Division by 0 will cause a FPE
>> shift
right
Don’t confuse & and &&..
1 & 2 0 whereas 1 && 2 <true>
13
14. Assignment Operators
x = y assign y to x x += y assign (x+y) to x
x++ post-increment x x -= y assign (x-y) to x
++x pre-increment x x *= y assign (x*y) to x
x-- post-decrement x x /= y assign (x/y) to x
--x pre-decrement x x %= y assign (x%y) to x
Note the difference between ++x and x++:
int x=5; int x=5;
int y; int y;
y = ++x; y = x++;
/* x == 6, y == 6 */ /* x == 6, y == 5 */
Don’t confuse = and ==! The compiler will warn “suggest parens”.
int x=5; int x=5;
if (x==6) /* false */ if (x=6) /* always true
{ */
/* ... */ {
recommendation
} /* x is now 6 */
/* x is still 5 */ }
/* ... */
14
15. A More Complex Program: pow
#include <stdio.h>
“if” statement #include <inttypes.h>
float pow(float x, uint32_t
/* if evaluated expression is not 0 */ exp)
if ( expression ) { {
/* then execute this block */ Need braces? /* base case */
} if (exp == 0) {
else { return 1.0;
X?Y:Z }
/* otherwise execute this block */
}
Short-circuit eval? detecting brace errors /* “recursive” case */
return x*pow(x, exp – 1);
}
Tracing “pow()”: int main(int argc, char
• What does pow(5,0) do? **argv)
{
• What about pow(5,1)? float p;
p = pow(10.0, 5);
• “Induction” printf(“p = %fn”, p);
return 0;
}
Challenge: write pow() so it requires log(exp) iterations
15
16. The “Stack”
#include <stdio.h>
Recall lexical scoping. If a variable is valid #include <inttypes.h>
“within the scope of a function”, what float pow(float x, uint32_t
happens when you call that function exp)
{
recursively? Is there more than one “exp”? /* base case */
if (exp == 0) { static
return 1.0;
Yes. Each function call allocates a “stack }
Java?
frame” where Variables within that function’s /* “recursive” case */
scope will reside. }
return x*pow(x, exp – 1);
int main(int argc, char
float x 5.0 **argv)
uint32_t exp 0 Return 1.0 {
float p;
float x 5.0 p = pow(5.0, 1);
printf(“p = %fn”, p);
uint32_t exp 1 Return 5.0 return 0;
}
int argc 1
char **argv 0x2342
float p undefined
5.0 Grows
16
17. Iterative pow(): the “while” loop
Other languages?
float pow(float x, uint
Problem: “recursion” eats stack space (in C). exp)
Each loop must allocate space for arguments {
int i=0;
and local variables, because each new call float result=1.0;
while (i < exp) {
creates a new “scope”. result = result * x;
i++;
}
Solution: “while” loop. }
return result;
loop: int main(int argc, char
if ( condition ) { while ( condition )
**argv)
statements ; {
{
goto loop; statements ;
float p;
} }
p = pow(10.0, 5);
printf(“p = %fn”, p);
return 0;
}
17
18. The “for” loop
The “for” loop is just shorthand for this “while” loop structure.
float pow(float x, uint float pow(float x, uint
exp) exp)
{ {
float result=1.0; float result=1.0;
int i; int i;
i=0; for (i=0; (i < exp); i++)
while (i < exp) { {
result = result * x; result = result * x;
i++; }
} return result;
return result; }
}
int main(int argc, char
int main(int argc, char **argv)
**argv) {
{ float p;
float p; p = pow(10.0, 5);
p = pow(10.0, 5); printf(“p = %fn”, p);
printf(“p = %fn”, p); return 0;
return 0; }
}
18
19. Referencing Data from Other Scopes
So far, all of our examples all of the data values we have
used have been defined in our lexical scope
float pow(float x, uint
exp)
{
float result=1.0;
int i; Nothing in this scope
for (i=0; (i < exp); i++)
{
result = result * x;
}
return result;
}
int main(int argc, char Uses any of these variables
**argv)
{
float p;
p = pow(10.0, 5);
printf(“p = %fn”, p);
return 0;
}
19
20. Can a function modify its arguments?
What if we wanted to implement a function pow_assign() that
modified its argument, so that these are equivalent:
float p = 2.0; float p = 2.0;
/* p is 2.0 here */ /* p is 2.0 here */
p = pow(p, 5); pow_assign(p, 5);
/* p is 32.0 here */ /* p is 32.0 here */
Would this work?
void pow_assign(float x, uint
exp)
{
float result=1.0;
int i;
for (i=0; (i < exp); i++) {
result = result * x;
}
x = result;
}
20
21. NO!
Remember the stack!
void pow_assign(float x, uint Java/C++?
exp)
{ In C, all arguments are
float result=1.0;
int i;
passed as values
for (i=0; (i < exp); i++) {
result = result * x;
}
x = result; But, what if the argument is
} the address of a variable?
{
float p=2.0;
pow_assign(p, 5);
}
float x 32.0
2.0
uint32_t exp 5
float result 32.0
1.0
float p 2.0 Grows
21
22. Passing Addresses
Symbol Addr Value
Recall our model for variables stored 0
in memory
1
2
What if we had a way to find out the
address of a symbol, and a way to 3
reference that memory location by char x 4 ‘H’ (72)
address? char y 5 ‘e’ (101)
address_of(y) == 6
5
memory_at[5] == 7
101
void f(address_of_char p)
{
8
memory_at[p] = memory_at[p] -
32;
9
}
10
char y = 101; /* y is 101 */
f(address_of(y)); /* i.e. f(5) 11
*/
/* y is now 101-32 = 69 */ 12
22
23. “Pointers”
This is exactly how “pointers” work.
A “pointer type”: pointer to char
“address of” or reference
operator: &
“memory_at” or dereference
operator: *
void f(address_of_char p) void f(char * p)
{ {
memory_at[p] = memory_at[p] - *p = *p - 32;
32; }
}
char y = 101; /* y is 101 */ char y = 101; /* y is 101 */
f(address_of(y)); /* i.e. f(5) */ f(&y); /* i.e. f(5) */
/* y is now 101-32 = 69 */ /* y is now 101-32 = 69 */
Pointers are used in C for many other purposes:
• Passing large objects without copying them
• Accessing dynamically allocated memory
• Referring to functions
23
24. Pointer Validity
A Valid pointer is one that points to memory that your program controls.
Using invalid pointers will cause non-deterministic behavior, and will
often cause Linux to kill your process (SEGV or Segmentation Fault).
There are two general causes for these errors: How should pointers be initialized?
• Program errors that set the pointer value to a strange number
• Use of a pointer that was at one time valid, but later became invalid
Will ptr be valid or invalid?
char * get_pointer()
{
char x=0;
return &x;
}
{
char * ptr = get_pointer();
*ptr = 12; /* valid? */
}
24
25. Answer: Invalid!
A pointer to a variable allocated on the stack becomes invalid when
that variable goes out of scope and the stack frame is “popped”. The
pointer will point to an area of the memory that may later get reused
and rewritten.
char * get_pointer()
{
char x=0;
return &x;
} But now, ptr points to a
{
location that’s no longer in
char * ptr = get_pointer(); use, and will be reused the
*ptr = 12; /* valid? */
other_function(); next time a function is called!
}
101 int x
charaverage Return 101
456603
12
0
100 char * ptr 101
? Grows
25
26. More on Types
We’ve seen a few types at this point: char, int, float, char *
Types are important because:
• They allow your program to impose logical structure on memory
• They help the compiler tell when you’re making a mistake
In the next slides we will discuss:
• How to create logical layouts of different types (structs)
• How to use arrays
• How to parse C type names (there is a logic to it!)
• How to create new types using typedef
26
27. Structures
Packing?
struct: a way to compose existing types into a structure
#include <sys/time.h> struct timeval is defined in this header
/* declare the struct */
struct my_struct { structs define a layout of typed fields
int counter;
float average;
struct timeval timestamp;
structs can contain other structs
uint in_use:1;
uint8_t data[0]; fields can specify specific bit widths
}; Why?
/* define an instance of A newly-defined structure is initialized
my_struct */
struct my_struct x = { using this syntax. All unset fields are 0.
in_use: 1,
timestamp: {
tv_sec: 200
}
}; Fields are accessed using ‘.’ notation.
x.counter = 1;
x.average = sum / (float)
(x.counter); A pointer to a struct. Fields are accessed
struct my_struct * ptr = &x;
using ‘->’ notation, or (*ptr).counter
ptr->counter = 2;
(*ptr).counter = 3; /* equiv. */
27
28. Arrays
Arrays in C are composed of a particular type, laid out in memory in a
repeating pattern. Array elements are accessed by stepping forward
in memory from the base of the array by a multiple of the element size.
/* define an array of 10 chars */ Brackets specify the count of elements.
char x[5] = {‘t’,’e’,’s’,’t’,’0’};
Initial values optionally set in braces.
/* accessing element 0 */
x[0] = ‘T’;
Arrays in C are 0-indexed (here, 0..9)
/* pointer arithmetic to get elt 3
*/ x[3] == *(x+3) == ‘t’ (NOT ‘s’!)
char elt3 = *(x+3); /* x[3] */
/* x[0] evaluates to the first What’s the difference Symbol Addr Value
element; between char x[] and
* x evaluates to the address of
char *x? char x [0] 100 ‘t’
the
* first element, or &(x[0]) */ char x [1] 101 ‘e’
For loop that iterates
/* 0-indexed for loop idiom */
char x [2] 102 ‘s’
#define COUNT 10 from 0 to COUNT-1. char x [3] 103 ‘t’
char y[COUNT];
int i;
Memorize it! char x [4] 104 ‘0’
for (i=0; i<COUNT; i++) {
/* process y[i] */
printf(“%cn”, y[i]);
} 28
29. How to Parse and Define C Types
At this point we have seen a few basic types, arrays, pointer types,
and structures. So far we’ve glossed over how types are named.
int x; /* int; */ typedef int T;
int *x; /* pointer to int; */ typedef int
typedef defines
*T; a new type
int x[10]; /* array of ints; */ typedef int
T[10];
int *x[10]; /* array of pointers to int; */ typedef int
C type names are parsed by starting at the type name and working
*T[10];
outwards according to thearray of ints; */ typedef int
int (*x)[10];
(*T)[10];
/* pointer to
rules of precedence:
x is
an array of
pointers to
int *x[10]; int Arrays are the primary
source of confusion. When
x is in doubt, use extra parens to
int (*x)
a pointer clarify the expression.
[10]; to
an array of
int
29
30. Function Types
For more details:
The other confusing form is the function type. $ man qsort
For example, qsort: (a sort function in the standard library)
void qsort(void *base, size_t nmemb, size_t size, The last argument is a
int (*compar)(const void *, const void *));
comparison function
/* function matching this type: */
int cmp_function(const void *x, const void *y);
const means the function
/* typedef defining this type: */ is not allowed to modify
typedef int (*cmp_type) (const void *, const void *); memory via this pointer.
/* rewrite qsort prototype using our typedef */
void qsort(void *base, size_t nmemb, size_t size, cmp_type
compar);
size_t is an unsigned int
void * is a pointer to memory of unknown type.
30
31. Dynamic Memory Allocation
So far all of our examples have allocated variables statically by
defining them in our program. This allocates them in the stack.
But, what if we want to allocate variables based on user input or other
dynamic inputs, at run-time? This requires dynamic allocation.
sizeof() reports the size of a type in bytes For details:
int * alloc_ints(size_t requested_count) $ man calloc
{ calloc() allocates memory
int * big_array;
big_array = (int *)calloc(requested_count,
for N elements of size k
sizeof(int));
if (big_array == NULL) { Returns NULL if can’t alloc
printf(“can’t allocate %d ints: %mn”,
requested_count); %m ? Emstar tips
return NULL;
} It’s OK to return this pointer.
/* now big_array[0] .. big_array[requested_count-1] It will remain valid until it is
are freed with free()
* valid and zeroed. */
return big_array;
}
31
32. Caveats with Dynamic Memory
Dynamic memory is useful. But it has several caveats:
Whereas the stack is automatically reclaimed, dynamic allocations must be
tracked and free()’d when they are no longer needed. With every
allocation, be sure to plan how that memory will get freed. Losing track of
memory is called a “memory leak”. Reference counting
Whereas the compiler enforces that reclaimed stack space can no longer
be reached, it is easy to accidentally keep a pointer to dynamic memory
that has been freed. Whenever you free memory you must be certain that
you will not try to use it again. It is safest to erase any pointers to it.
Because dynamic memory always uses pointers, there is generally no way
for the compiler to statically verify usage of dynamic memory. This means
that errors that are detectable with static allocation are not with dynamic
32
33. Some Common Errors and Hints
sizeof() can take a variable reference in place of a type name. This gurantees the right
allocation, but don’t accidentally allocate the sizeof() the pointer instead of the object!
/* allocating a struct with malloc() */ malloc() allocates n bytes
struct my_struct *s = NULL;
s = (struct my_struct *)malloc(sizeof(*s)); /* NOT
sizeof(s)!! */ Why?
if (s == NULL) { Always check for NULL.. Even if you just exit(1).
printf(stderr, “no memory!”);
exit(1);
} malloc() does not zero the memory,
so you should memset() it to 0.
memset(s, 0, sizeof(*s));
/* another way to initialize an alloc’d structure: */
struct my_struct init = {
counter: 1,
average: 2.5,
in_use: 1
};
/* memmove(dst, src, size) (note, arg order like assignment)
*/ memmove is preferred because it is
memmove(s, &init, sizeof(init)); safe for shifting buffers
Why?
/* when you are done with it, free it! */
free(s); Use pointers as implied in-use flags!
s = NULL;
33
34. Macros
Macros can be a useful way to customize your interface to C and
make your code easier to read and less redundant. However, when
possible, use a static inline function instead. What’s the difference between a
macro and a static inline function?
Macros and static inline functions must be included in any file that
uses them, usually via a header file. Common uses for macros:
More on C
/* Macros are used to define constants */ constants?
#define FUDGE_FACTOR 45.6 Float constants must have a decimal
#define MSEC_PER_SEC 1000 point, else they are type int
#define INPUT_FILENAME “my_input_file”
enums
/* Macros are used to do constant arithmetic */
Why?
#define TIMER_VAL (2*MSEC_PER_SEC) Put expressions in parens.
/* Macros are used to capture information from the compiler */
#define DBG(args...)
do { Multi-line macros need
fprintf(stderr, “%s:%s:%d: “,
__FUNCTION__, __FILE__, __LINENO__); args… grabs rest of args
fprintf(stderr, args...);
} while (0) Why?
Enclose multi-statement macros in do{}while(0)
/* ex. DBG(“error: %d”, errno); */
34
35. Macros and Readability
Sometimes macros can be used to improve code readability… but
make sure what’s going on is obvious.
/* often best to define these types of macro right where they are used */
#define CASE(str) if (strncasecmp(arg, str, strlen(str)) == 0)
void parse_command(char *arg)
void parse_command(char *arg)
{
{
CASE(“help”) {
if (strncasecmp(arg, “help”,
/* print help */
strlen(“help”)) {
}
/* print help */
CASE(“quit”) {
}
exit(0);
if (strncasecmp(arg, “quit”,
}
strlen(“quit”)) {
}
exit(0);
}
/* and un-define them after use */
}
#undef CASE
Macros can be used to generate static inline functions. This is like a C
version of a C++ template. See emstar/libmisc/include/queue.h for an
example of this technique.
35
36. Using “goto”
Some schools of thought frown upon goto, but goto has its place. A
good philosophy is, always write code in the most expressive and
clear way possible. If that involves using goto, then goto is not bad.
An example is jumping to an error case from inside complex logic.
The alternative is deeply nested and confusing “if” statements, which
are hard to read, maintain, and verify. Often additional logic and state
variables must be added, just to avoid goto.
goto try_again;
goto fail;
36
37. Unrolling a Failed Initialization using goto
state_t *initialize()
{ state_t *initialize()
/* allocate state struct */ {
state_t *s = g_new0(state_t, 1); /* allocate state struct */
if (s) { state_t *s = g_new0(state_t, 1);
/* allocate sub-structure */ if (s == NULL) goto free0;
s->sub = g_new0(sub_t, 1);
if (s->sub) { /* allocate sub-structure */
/* open file */ s->sub = g_new0(sub_t, 1);
s->sub->fd = if (s->sub == NULL) goto free1;
open(“/dev/null”,
O_RDONLY); /* open file */
if (s->sub->fd >= 0) { s->sub->fd =
/* success! */ open(“/dev/null”, O_RDONLY);
} if (s->sub->fd < 0) goto free2;
else {
free(s->sub); /* success! */
free(s); return s;
s = NULL;
} free2:
} free(s->sub);
else { free1:
/* failed! */ free(s);
free(s); free0:
s = NULL; return NULL;
} }
}
return s;
}
37
38. High Level Question: Why is Software Hard?
Answer(s):
• Complexity: Every conditional (“if”) doubles number of paths
through your code, every bit of state doubles possible states
– Solution: reuse code paths, avoid duplicate state variables
• Mutability: Software is easy to change.. Great for rapid fixes ..
And rapid breakage .. always one character away from a bug
– Solution: tidy, readable code, easy to understand by inspection.
Avoid code duplication; physically the same logically the same
• Flexibility: Programming problems can be solved in many
different ways. Few hard constraints plenty of “rope”.
– Solution: discipline and idioms; don’t use all the rope
38
39. Addressing Complexity
• Complexity: Every conditional (“if”) doubles number of paths
through your code, every bit of state doubles possible states
– Solution: reuse code paths, avoid duplicate state variables
reuse code paths
On receive_packet:
if queue full, drop packet
else push packet, call run_queue On input, change our state as needed, and
On transmit_complete:
call Run_queue. In all cases, Run_queue
state=idle, call run_queue handles taking the next step…
Run_queue:
if state==idle && !queue empty
pop packet off queue
start transmit, state = busy
39
40. Addressing Complexity
• Complexity: Every conditional (“if”) doubles number of paths
through your code, every bit of state doubles possible states
– Solution: reuse code paths, avoid duplicate state variables
avoid duplicate state variables
int transmit_busy; msg_t *packet_on_deck;
msg_t *packet_on_deck;
int start_transmit(msg_t *packet)
int start_transmit(msg_t *packet) {
{ if (packet_on_deck != NULL)
if (transmit_busy) return -1; return -1;
/* start transmit */ /* start transmit */
packet_on_deck = packet; packet_on_deck = packet;
transmit_busy = 1;
/* ... */
/* ... */ return 0;
return 0; }
} Why return -1?
40
41. Addressing Mutability
• Mutability: Software is easy to change.. Great for rapid fixes ..
And rapid breakage .. always one character away from a bug
– Solution: tidy, readable code, easy to understand by inspection.
Avoid code duplication; physically the same logically the same
Tidy code.. Indenting, good formatting, comments, meaningful variable and
function names. Version control.. Learn how to use CVS
Avoid duplication of anything that’s logically identical.
struct pkt_hdr {
int source; struct pkt_hdr {
int dest; int source;
int length; int dest; Otherwise when
int length;
};
struct pkt { };
one changes, you
int source; struct pkt { have to find and fix
struct pkt_hdr hdr;
int dest;
int length; uint8_t
all the other places
uint8_t payload[100];
payload[100]; };
};
41
42. Solutions to the pow() challenge question
Recursive Iterative
float pow(float x, uint exp)
{
float result; float pow(float x, uint exp)
{
/* base case */ float result = 1.0;
if (exp == 0)
return 1.0; int bit;
for (bit = sizeof(exp)*8-1;
/* x^(2*a) == x^a * x^a */ bit >= 0; bit--) {
result = pow(x, exp >> 1); result *= result;
result = result * result; if (exp & (1 << bit))
result *= x;
/* x^(2*a+1) == x^(2*a) * x }
*/
if (exp & 1) return result;
result = result * x; }
return result;
}
Which is better? Why?
42
Editor's Notes
In my first summer internship my task was to convert a numeric program from FORTRAN to C, knowing nothing about either language – I only knew Pascal and BASIC. The result was that I sort of learned C, but in a sort of voodoo way, never really being sure what was going on, but getting some things to work, at least some of the time. Since then I’ve gradually worked out how things really work, and really make sense, and become proficient…. But this was a slow process. Today I hope to help shortcut some of that process. How this is going to proceed. I have limited time here so I will go kind of fast. I may mention some things in passing that I won’t fully explain. However, afterwards you will have the .ppt file and the notes. All the stuff I mention in passing is in the slides and the notes. This way, even if you don’t “get” all the details the first time, you can go back and refer to the slides and notes.
Gcc compiler options: -Wall tells the compiler to generate ALL “warnings”. These warnings will often identify stupid mistakes. -g tells the compiler to generate debugging information If you don’t supply a –o option to set an output filename, it will create an executable called “a.out” ./? To run a program in the current directory use ./program ‘.’ is the current directory. Otherwise the shell will only run program that are in your “PATH” variable, which is usually “standard” paths like /bin and /usr/bin What if it doesn’t work? If your program compiles but doesn’t work, there are many debugging tools at your disposal. “ strace” traces all system calls made by your program. This will tell you when you call into the OS, e.g. open(), read(), write(), etc. “ ltrace” traces all standard library calls made by your program. “ gdb” is a source-level debugger. With this tool you can analyse core dumps, and step through your program line by line as it runs. “ valgrind” is an x86 virtual machine that is useful for catching memory errors such as use of freed memory, bad pointers, etc. Another common way to trace a program is “printf debugging”, where you put printf statements throughout your code to see what’s going on.
What do the <> mean? Include directives use <x.h> (brackets) to indicate that the compiler should look in a “standard” place, such as /usr/include/… They use “x.h” (double quotes) to indicate that it should look first in the current directory. Can your program have more than one .c file? A ‘.c’ file is called a “module”. Many programs are composed of several ‘.c’ files and libraries that are ‘linked’ together during the compile process.
Why preprocess? Having two phases to a process with different properties often helps to make a very flexible yet robust system. The underlying compiler is very simple and its behavior is easily understood. But because of that simplicity it can be hard to use. The preprocessor lets you “customize” the way your code “looks and feels” and avoid redunancy using a few simple facilities, without increasing the complexity of the underlying compiler. Macros can be used to make your code look clean and easy to understand. They can also be used for “evil”. What are continued lines? Continued lines are lines that need to be very long. When the preprocessor encounters a ‘\\’ (that is not inside a string), it will ignore the next character. If that character is a newline, then this “eats” the newline and joins the two lines into one. This is often used when defining macros with #define, because a macro must be all on one line. Be careful! If you have a space after a ‘\\’, it will eat the space and will NOT join the lines.
Include directives use <x.h> (brackets) to indicate that the compiler should look in a “standard” place, such as /usr/include/… They use “x.h” (double quotes) to indicate that it should look first in the current directory.
What’s 72? ASCII is the coding scheme that maps bytes to characters. Type ‘man ascii’ at the shell to get a listing of the mapping. Not always… Types such as int vary in size depending on the architecture. On a 32 bit or 64 bit platform, ints are 4 bytes (32 bits). On an 8 or 16 bit platform, an int is 2 bytes (16 bits). To be safe, it’s best to specify types exactly e.g. int32_t, int16_t., int8_t. Defined in #include <inttypes.h> Signed? Signedness is a common source of problems in C. It’s always clearest to specify signness explicitly (and size) using the [u]int[8,16,32]_t types. Signedness can introduce surprises when casting types because of “sign extension”. For example, char is signed (although it’s normally used as unsigned 0-255). If you cast char to int, it will be a signed integer and the sign will be extended. If you then cast that to unsigned, it turns a small negative number into an enormous int value (high bit set). That is, (uint32_t)(int)(char)(128) == 4294967168 (not 128!) One easy solution to this is to always use uint8_t rather than char for byte streams.
Symbol table: The “Symbol Table” is the mapping from symbol to address. You can extract this from a compiled program (if debugging is enabled aqt compile time with –g) using the nm utility. Declaration and definition mean slightly different things in C. Declaration is mapping a name to a type, but not to a memory location. Definition maps a name and type to a memory location (which could be the body of a function). Definitions can assign an initial value. Declarations can point to something that never actually gets defined, or is defined in a library external to your program. What names are legal? Symbols in C (function and variable names) must start with an alphabetic character or ‘_’. They may contain numeric digits as well but cannot start with a digit. Common naming strategies are ‘CamelCase’, ‘lowerUpper’, and ‘under_bar’. Some people use complicated schemes but I prefer under_bar. extern, static, and const are modifiers of variable declarations. ‘extern’ means the variable being declared is defined elsewhere in some other program module (.c file). ‘static’ means that the variable cannot be accessed outside of the current scope. ‘const’ means the variable’s value cannot be changed (directly).
Returns nothing.. “void” is used to denote that nothing is returned, or to indicate untyped data. What if you define a new “char b”? What happens to the old one? If you defile a variable in your local scope that has the same name as a variable in an enclosing scope, the local version takes precedence. Are definitions allowed in the middle of a block? Older versions of C and some derivatives like NesC only allow definitions at the beginning of a scope; d would be illegal. Modern C (gcc 3.0+) allows this, which can make the code easier to read as the definitions are closer to use. However, note that definitions are not always allowed in certain places, such as after a jump target, e.g. { goto target; /* … */ target: int z; /* error */ /* … */ }
Despite being syntactically correct, if (x=y) is generally to be avoided because it is confusing. Doing complicated things with ++ and – are also not generally recommended. It is almost never important from an efficiency perspective and it just makes the code harder to understand.
Need braces? Braces are only needed if your block contains a single statement. However, braces, even when not necessary, can increase the clarity of your code, especially when nesting ‘if’ statements. X ? Y : Z.. There is a shortcut to if then else that can be done in an expression: the ‘?:’ syntax. (cond ? alt1 : alt2) is an expression returning alt1 if cond, and alt2 if not cond. There is no truly equivalent form to this construct. Short circuit evaluation. Sometimes when evaluating an if conditional, the result is known before the evaluation completes. For example, consider if (X || Y || Z). If X is true, then Y and Z don’t matter. C will not evaluate Y and Z if X is true. This only matters in cases where there are side effects of evaluating the rest of the expression, for example if it contains function calls, or invalid operations. The converse evaluation rules apply to &&; if (X && Y && Z) will only evaluate Y and Z if X is true. Note, this is why it’s OK to write: char *x; if ((x != NULL) && (*x == ‘Z’)) … because if x is NULL (and therefore an invlalid pointer) the second clause dereferencing x will not be run. Note that this means that it’s not always possible to replace an if() with a function call because all args to a function are evaluated before calling the function. Detecting brace errors . Many text editors such as emacs include features that help you detect brace errors. Emacs will remind you of the opening brace whenever you close a brace, and will auto-indent your code according to braces – wrong indenting gives you a hint that something is wrong. In emacs, <tab> will autoindent the line you are on.. Keeping your code properly indented is a good way to detect a lot of different kinds of error.
Variables declared ‘static’ inside of a function are allocated only once, rather than being allocated in the stack frame when the function is called. Static variables therefore retain their value from one call to the next, but may cause problems for recursive calls, or if two threads call the function concurrently. Java users: Just to be aware: recursion doesn’t always work in Java because objects are always passed by reference (i.e they are not copied). In java, this recursive function would only work if it was a primitive type like int being passed.
What about other languages? Some languages such as scheme implement optimized “tail recursion”, which reuses the current stack frame when the recursive call constitutes the last use of the current stack frame. In these cases, recursion costs no more than iteration.
Java In java, primitive types like int are passed by value, but all objects are passed by reference (basically by pointer, but without any explicit awareness of the address). In C++, things operate like in C except that there is a syntax to pass arguments by reference, declaring the argument to be a “reference” type. For example, int f(int &x); C does not support this; you have to do it “manually” with pointers. But it’s not really fundamentally different anyway.
How should pointers be initialized? Always initialize pointers to 0 (or NULL). NULL is never a valid pointer value, but it is known to be invalid and means “no pointer set”.
Packing? The layout of a structure in memory is actually architecture-dependent. The order of the fields will always be preserved; however, some architectures will pad fields so that they are word-aligned. Word alignment is important for some processor architectures because they do not support unaligned memory access, e.g. accessing a 4 byte int that is not aligned to a 4 byte boundary. It is also usually more efficient to process values on word boundaries. So in general, structs are architecture-specific. For instance, on x86 platforms, all fields are word-aligned, so struct { uint16_t x; uint32_t y; }; Will have a hidden two bytes of padding between x and y. However, on an atmel atmega128 this padding will not be present. One way to address this is to predict it, and explicity add the padding fields. Another solution is to add __attribute__ ((“packed”)) after the structure declaration to force the compiler to generate code to handle unaligned accesses. This code will operate slower but this is often the easiest solution to dealing with cross-platform compatibility. The other common problem with cross-platform compatibility is endianness. X86 machines are little-endian; many modern processors such as the PXA (xscale) can select their endianness. The functions ntohl, htonl, etc. can be used to convert to a standard network byte order (which is big endian). =========== Why a zero length array? A zero length array is a typed “pointer target” that begins at the byte after the end of the struct. The zero length array takes up no space and does not change the result of sizeof(). This is very useful for referring to data following the struct in memory, for example if you have a packet header and a packet payload following the header: struct hdr { int src; int dst; uint8_t data[0]; }; If you have a buffer of data containing the packet and the payload: uint8_t buf[200]; int buf_len; /* cast the buffer to the header type (if it’s long enough!) */ if (buf_len >= sizeof(struct hdr)) { struct hdr *h = (struct hdr *)buf; /* now, h->data[0] is the first byte of the payload */ }
char x[] and char *x are subtlely different. First, what’s the same: both will evaluate to an address that is type char *. In both cases, x[n] == *(x+n) and x == &(x[0]). The difference lies in the fact that char x[10] allocates memory for that data and both &x and x always evaulates to the base address of the array, whereas char *x allocates only space for a pointer, and x simply evaulates to the value of that pointer. Thus, in the case of char x[10], &x == x by definition. However this is almost never true for char *x because x contains the address of the memory where the characters are stored, &(x[0]), and &x is the address of that pointer itself!
%m: When %m is included in a printf format string, it prints a string naming the most recent error. A global variable ‘errno’ always contains the most recent error value to have occurred, and the function strerr() converts that to a string. %m is shorthand for printf(“%s”, strerr(errno)) Emstar tips : Emstar includes glib which includes various useful functions and macros. One of these is g_new0(). g_new0(typename, count) (typename *)calloc(count, sizeof(typename)); Emstar also provides elog() and elog_raw(), logging functions that integrate with emstar’s logging facilities. elog() works like printf, but takes one additional loglevel argument. You do not need to include a ‘\\n’ in elog() messages as it is implied. elog_raw() takes a buffer and a length and dumps the bytes out in a prettyprinted fashion. Emstar includes the useful “buf_t” library that manages automatically growing buffers. This is often the easiest way to allocate memory.
Reference counting is one approach to tracking allocated memory. However, there is no perfect scheme. The main problem with reference counting is that correctly handling cyclically linked structures is very difficult, and likely to result in mis-counting in one direction or the other. Garbage collection is another solution; this is used by Java and other languages. However, this often causes performance problems and requires a very strict control over typing in the language, which C can’t easily provide by its nature of having direct access to the low levels. Emstar uses a static reference model, where there is exactly one canonical reference to each object, and that reference will be automatically cleared when the object is destroyed. The only requirements are: the reference must be in stable allocation (static or dynamic, but you can’t move the memory) and you must always access the object via that single reference. We have found this scheme to be quite workable, as long as you are cognizant of these requirements.
What to do when malloc fails? Except in certain cases, it’s going to be very difficult to recover from this state because lots of functions will start failing and the correct way to handle these errors is not obvious. If you continue without your memory, it is likely that your program will get into some very seriously broken state. The main case where recovery IS possible is the case that the malloc() that failed is part of a single too-large transaction that can fail independently of the rest of the system. For example if the user asks your program to allocate a zillion bytes and you can’t, just abort that request and ask for the next request. But if your system is just generally out of memory, there’s not much you can do. In emstar, processes automatically respawn and the system is generally designed to handle module failures, so a slow memory leak that causes you to exit and restart may allow a fairly graceful recovery. Memmove memmove() is written so that it will copy in the correct order to be able to shift data in a buffer, that is, if the source and destination buffers overlap. This is not true of the memcpy() function. Use pointers as implied in-use flags! One clever way to reduce the number of state variables is to avoid the use of “in use” flags when there is also a pointer that can be NULL. That is, if the item is not allocated (and therefore a NULL pointer), it’s not in use. If there’s a pointer there, then you assume that it is valid, initialized, etc. By avoiding this redundancy of state varaibles, you avoid the various cases where the two variables are out of sync.. Pointer there but not in use.. Or in use but no pointer.
The difference between a macro and a static inline . These two constructs have some properties in common: they must be included in any module that uses them, they can’t be linked to, and they are generally inlined into the program. The key difference between them is that the macro is processed by the preprocessor whereas the static inline conforms to all of the semantics of any other function. The reason it must be included in each file is that it’s declared static, and the reason it’s more efficient is that it is inlined by default. Static inlines cause their arguments to be evaluated before being applied whereas macros are a pure text substitution with no evaluation. Arguments to static inlines are type-checked whereas arguments to macros can be any type and are substituted as raw text. Static inline invocations can invoke statements AND return a value, whereas a macro can EITHER return a value (if it’s an expression) OR invoke statements. A good example of the differences is the implementation of sqr(): #define SQR(a) ((a)*(a)) static inline float sqr(float a) { return a*a; } SQR will evaulate its argument twice, i.e. SQR(x++) will compute x*(x+1) sqr will evaliate its argument once, i.e. sqr(x++) will compute x*x SQR can compute the square of any numberic quantity, whereas sqr can only handle floats. However, sqr will return a more helpful error message if you attempt to square a struct. Since macros can do text manipulation, one nice way to use them is to use macros to generate static inlines. More on C constants . Check K&R for the details on the modifiers that allow you to correctly type constants. For example, 45L is a long int. Watch out for preceding 0’s, this means it will interpret it as octal. These issues most often crop up when you are trying to specify a constant that is larger than the default int type. Enums: For defining sets of integer values, enums are preferable. Enums enforce uniqueness within an enum and can automatically number your values sequentially. But macros are preferred for constants that define tuning parameters (that don’t want uniqueness or sequential values) and other types like floats and strings. Why expressions in parens : If you leave off the parens then your expression may introduce precedence surprises when combined in other expressions. For example: #define VALUE 2+45 int c = VALUE*3; What was meant was (2+45)*3 .. But what we got was 2+(45*3) It’s also a good idea to put parens around args of a macro, to avoid similar problems if one of the args is an expression: #define SQR(x) ((x)*(x)) Why use do{}while(0)? Multi-statement macros should be enclosed in do{}while(0) to avoid surprises when the macro is called as one statement in an if (): if (fail) DBG(“help\\n”); would cause only the first statement to be conditional.
Why return -1? Return values in C are usually 0 or positive for success and negative to signal failure. The errno codes (man errno) list some meanings that can be used for error return codes. When a pointer is returned, NULL signifies a failure. Errno can be set to indicate a reason for the failure (by just assigning to errno).
The recursive solution uses more stack space, but only a limited amount (max. 32 recursions), is easier to read and understand. Readability is valuable and not worth sacrificing to optimality unless there is a good reason to optimize. So I vote for recursion in this case.