It is the meaning of an expression in a programming language.Sematics offers formalization which helps to prove the correctness of a program. The effect of an execution of the program
can be formalized by axioms that describe how the statement transforms a state that satisfies an input assertion (logical formula) to a state that satisfies an output assertion and if the input data satisfies the input assertion, then the output data satisfies the output assertion.
The abstract definition of a type is a set of values (eg the set of all values of 32-bit words) plus a set of operations on those values (eg integer +, -, *, ==, etc; note that something like + has an entirely different implementation for type double, and perhaps yet another implementation for type string). In C++, a user-defined abstract type is commonly viewed as a class. The values of the type are the set of legal combinations of member values (note that not all member value combinations may be legal), and the operations are just the member (and friend) functions of the class. The idea of abstract types, however, applies to concrete types as well. For instance, C arrays are values that support the [ ], etc operations. Ints are, say, 32-bit values that support not only + - * / but also the bitwise operations & | ^ << >>. In Pascal, on the other hand, the bit operations do not apply to integers; there is a separate "set of ..." type which supports them (and only them). In general, higher-level languages provide more different kinds of types, and more specific types (that is, each type has fewer operations) than lower-level languages. Even assembly language has types, although the types tend to be things like "machine word" and have very large sets of legal operations.
In short, all programming languages provide one or more basic types, and usually some way of defining new types. The basic operations provided by the language determine the exact nature of these basic types. Each variable, and each expression, can have a type assigned to it. A type system is a set of rules for associating each expression with a type; it consists of rules (generally derived from declarations) for the type of each variable, plus rules for the result type of operators, given the types of the operands. Some languages enforce their type systems rigidly; other languages allow the programmer to bypass the type system when appropriate (or perhaps when inappropriate!). Type systems may allow more than one assignment of type (eg an expression might be either short or int), although the language inevitably has rules for resolving ambiguities.
Type inference may be possible at compile time, in which case the language is said to be statically typed. For example, if we have declared variable n to have type int, the compiler can determine that the expression (n+1) is also int, and that (n+1.0) is of type double (because 1.0 is of type double). Some types (notably "subtypes") cannot be checked at compile time. For example, if we declare n to be a positive integer (there is a technical difference between this and "unsigned"), then after the assignment n=x the language must verify at runtime that n is still positive; this is similar to checking at runtime that when accessing an array component A[i], the index variable i is within the proper range. In object-oriented languages, if c is of type Base then assignments of the form "c = new Deriv()" are generally allowed, and the question whether c represents a Base object or a Deriv object can only be settled at runtime. Certain Java "container" classes have components of type Object; the programmer can put any object type into such a container as every object type is derived from Object, but type checking as things are taken out of the container ineluctably moves to run-time.
Static type checking is usually seen as a help (albeit a sometimes-annoying help) to the programmer: type errors can be caught before the program is run. In dynamically-typed languages, and in dynamically-typed situations in otherwise statically-typed languages, the compiler cannot verify type consistency. The language Lisp is entirely dynamically typed. For the programmer this is a tradeoff. On the one hand, variables can take values of any type, and so a function to calculate the length of a list doesn't need separate versions for lists-of-numbers and lists-of-strings. On the other hand, nothing will prevent the programmer from adding 3 and "hello", or taking the next element of the "list" 3.14159; both
Data is considered as most important element of Programming language.In early programming languages the actions were performed on physical entities such as registers and memory cells
But now we use a type which is a set of values and a set of operations on those values.For example int in C is a type consisting of a finite set of values and set of operations (+, <=) we can perform on those values. There are some terms which are used with data :-Value( An undefined primitive concept) , Literal( A specific value is denoted in a program by a literal, which is a sequence of symbols, for example: 154, 45.6, FALSE) , Representation (A value represented within a computer by a specific string of bits) , Variable (A name given to the memory cell or cells that can hold the representation of a value of a specific type ,which can be changed during the execution of the program) ,Constant (A name given to the memory cell or cells that can hold the representation of a value of a specific type , which may not be changed during the execution of the program) , Object (An object is a variable or a constant).
Assignment statement sets the values stored in storage location denoted by a variabledenoted by a variable name. The other statements just control the sequence of execution of assignment statements.
Type checking is a process of identifying errors in a program based on explicitly or implicitly stated type information.It may occur either at compile time or run time.These typing may be weak typing ,strong typing and static typing.The more type checking that is done
the more reliable a program will be, but it will require more programming effort to define an
appropriate set of type.It should be possible to bypass type checking but conversely, if little type checking is done it is easy to write a program, but it then becomes difficult
to find bugs and to ensure the reliability of the program. Another disadvantage to type checking
is that it may require run-time overhead to implement. Strong type checking can eliminate obscure bugs which are usually caused by such errors or misunderstandings.Strong type checking attempts to transform run-time errors into compile-time errors. Run-time
errors can be extremely difficult to find, dangerous and expensive during development of the software .
Control statements are used to modify the order of execution , where as the assignment are executed in an ordered sequence in which they are written. Structured programming is the name given to the programming style which restricts the use of control statements to those which yield well-structured programs that are easy to read and un derstand.They two classes of statement i.e choice statement (if statement and case statement) and loop statement (for statement and while statement).
This grammar specifies the following:
an expression is either an atom or a list;
an atom is either a number or a symbol;
a number is an unbroken sequence of one or more decimal digits, optionally preceded by a plus or minus sign;
a symbol is a letter followed by zero or more of any characters (excluding whitespace); and
a list is a matched pair of parentheses, with zero or more expressions inside it.
The following are examples of well-formed token sequences in this grammar: '12345', '()', '(a b c232 (1))'
Not all syntactically correct programs are semantically correct. Many syntactically correct programs are nonetheless ill-formed, per the language's rules; and may (depending on the language specification and the soundness of the implementation) result in an error on translation or execution. In some cases, such programs may exhibit undefined behavior. Even when a program is well-defined within a language, it may still have a meaning that is not intended by the person who wrote it.
Using natural language as an example, it may not be possible to assign a meaning to a grammatically correct sentence or the sentence may be false:
"Colorless green ideas sleep furiously." is grammatically well-formed but has no generally accepted meaning.
"John is a married bachelor." is grammatically well-formed but expresses a meaning that cannot be true.
The following C language fragment is syntactically correct, but performs an operation that is not semantically defined (because p is a null pointer, the operations p->real and p->im have no meaning):
complex *p = NULL;
complex abs_p = sqrt (p->real * p->real + p->im * p->im);
If the type declaration on the first line were omitted, the program would trigger an error on compilation, as the variable "p" would not be defined. But the program would still be syntactically correct, since type declarations provide only semantic information.
The grammar needed to specify a programming language can be classified by its position in the Chomsky hierarchy. The syntax of most programming languages can be specified using a Type-2 grammar, i.e., they are context-free grammars. Some languages, including Perl and Lisp, contain constructs that allow execution during the parsing phase. Languages that have constructs that allow the programmer to alter the behavior of the parser make syntax analysis an undecidable problem, and generally blur the distinction between parsing and execution. In contrast to Lisp's macro system and Perl's BEGIN blocks, which may contain general computations, C macros are merely string replacements, and do not require code execution.
 Static semantics
The static semantics defines restrictions on the structure of valid texts that are hard or impossible to express in standard syntactic formalisms. For compiled languages, static semantics essentially include those semantic rules that can be checked at compile time. Examples include checking that every identifier is declared before it is used (in languages that require such declarations) or that the labels on the arms of a case statement are distinct. Many important restrictions of this type, like checking that identifiers are used in the appropriate context (e.g. not adding a integer to a function name), or that subroutine calls have the appropriate number and type of arguments can be enforced by defining them as rules in a logic called a type system. Other forms of static analyses like data flow analysis may also be part of static semantics. Newer programming languages like Java and C# have definite assignment analysis, a form of data flow analysis, as part of their static semantics.
 Type system
Main articles: Type system and Type safety
A type system defines how a programming language classifies values and expressions into types, how it can manipulate those types and how they interact. The goal of a type system is to verify and usually enforce a certain level of correctness in programs written in that language by detecting certain incorrect operations. Any decidable type system involves a trade-off: while it rejects many incorrect programs, it can also prohibit some correct, albeit unusual programs. In order to bypass this downside, a number of languages have type loopholes, usually unchecked casts that may be used by the programmer to explicitly allow a normally disallowed operation between different types. In most typed languages, the type system is used only to type check programs, but a number of languages, usually functional ones, perform type inference, which relieves the programmer from writing type annotations. The formal design and study of type systems is known as type theory.
 Typed versus untyped languages
A language is typed if the specification of every operation defines types of data to which the operation is applicable, with the implication that it is not applicable to other types. For example, "this text between the quotes" is a string. In most programming languages, dividing a number by a string has no meaning. Most modern programming languages will therefore reject any program attempting to perform such an operation. In some languages, the meaningless operation will be detected when the program is compiled ("static" type checking), and rejected by the compiler, while in others, it will be detected when the program is run ("dynamic" type checking), resulting in a runtime exception.
A special case of typed languages are the single-type languages. These are often scripting or markup languages, such as REXX or SGML, and have only one data type-most commonly character strings which are used for both symbolic and numeric data.
In contrast, an untyped language, such as most assembly languages, allows any operation to be performed on any data, which are generally considered to be sequences of bits of various lengths. High-level languages which are untyped include BCPL and some varieties of Forth.
In practice, while few languages are considered typed from the point of view of type theory (verifying or rejecting all operations), most modern languages offer a degree of typing. Many production languages provide means to bypass or subvert the type system.
 Static versus dynamic typing
In static typing all expressions have their types determined prior to the program being run (typically at compile-time). For example, 1 and (2+2) are integer expressions; they cannot be passed to a function that expects a string, or stored in a variable that is defined to hold dates.
Statically typed languages can be either manifestly typed or type-inferred. In the first case, the programmer must explicitly write types at certain textual positions (for example, at variable declarations). In the second case, the compiler infers the types of expressions and declarations based on context. Most mainstream statically typed languages, such as C++, C# and Java, are manifestly typed. Complete type inference has traditionally been associated with less mainstream languages, such as Haskell and ML. However, many manifestly typed languages support partial type inference; for example, Java and C# both infer types in certain limited cases.
 Weak and strong typing
Subprograms were used just to enable reuse of a program segment but now they are essential element of program structure,
Where every program segment that does some identifiable task should be placed in a separate
subprogram. A subprogram is a unit consisting of data declarations and executable statements that can be invoked repeatedly from different parts of a program.Whenever a subprogram is called, it is passed a sequence of values called parameters. Parameters are
used to modify each execution of the subprogram, to send data to the subprogram, and to receivethe results of a computation.
Now a days programming languages contain an additional structuring method for encapsulating data and subprograms within larger entities called modules.These modules advances over bureaucracy is(set of rules which help in writing a program) that the interfaces between modules can be checked during compilation to prevent errors and misunderstandings.Two difficulties in in using modules were : A powerful program development environment is needed to keep track of the modules and to check the interfaces , secondly Modularization encourages the use of many small subprograms with the corresponding runtime overhead of the subprogram call.
But now a days the average personal computer is more than adequate to run
an environment for C++ or Ada, and modern computer architectures and compilation techniques
minimize the overhead of calls, which have overcome the disadvantage of module.