The PICTURE attribute specifies the properties of a character data item by associating a picture character with each position of the data item. A picture character specifies a category of characters that can occupy that position.
|
A numeric picture specification specifies arithmetic attributes of numeric character data in much the same way that they are specified by the appearance of a constant.
Numeric character data has an arithmetic value but is stored in character form. Numeric character data is converted to coded arithmetic before arithmetic operations are performed.
The base of a numeric character data item is decimal. Its scale is either fixed-point or floating-point (the K or E picture character denotes a floating-point scale). The precision of a numeric character data item is the number of significant digits (excluding the exponent in the case of floating-point). Significant digits are specified by the picture characters for digit positions and conditional digit positions. The scaling factor of a numeric character data item is derived from the V or the F picture character or the combination of V and F.
Only decimal data can be represented by picture characters. Complex data can be declared by specifying the COMPLEX attribute along with a single picture specification that describes either a fixed-point or a floating-point data item.
For more information on numeric character data, see Numeric character data.
Data with the CHARACTER attribute can contain any of the 256 characters supported by the character set. Data with the PICTURE attribute must have characters that match the picture-specification characters. Each character occupies 1 byte of storage.
A character constant is a contiguous sequence of characters enclosed in single or double quotation marks.
Quotation marks included in the constant follow the rules listed in Using quotation marks. The length of a character constant is the number of characters between the enclosing quotation marks counting any doubled quotation marks as a single character.
A null character constant is written as two quotation marks with no intervening blank. The syntax for a character constant is:
|
Examples of character constants are:
In the last example, the number in parentheses is a string repetition factor, which indicates repetition of the characters that follow. This example is equivalent to the constant "Walla Walla ". The string repetition factor must be a constant and enclosed in parentheses.
The X character constant is a contiguous sequence of an even number of hex digits enclosed in single or double quotation marks and followed immediately by the letter X. Each pair of hex digits represents one character.
The length of an X constant is half the number of hex digits specified.
A null X constant is written as two quotation marks followed by the X suffix.
|
Examples of X constants are:
Data with the BIT attribute allows manipulation of storage in terms of bits. Each byte of storage is composed of 8 bits.
A bit constant is a contiguous sequence of binary digits enclosed in single or double quotation marks and followed immediately by the letter B.
|
A null bit constant is written as two quotation marks, followed by B.
Examples of bit constants are:
The number in parentheses in the third example is a string repetition factor which specifies that the following series of bits is repeated the specified number of times. The example shown would result in a string of 64 zero bits.
(See Source-to-target rules for a discussion on the conversion of bit-to-character data and character-to-bit data.)
The B4 bit constant is a contiguous sequence of hex digits enclosed in single or double quotation marks and followed immediately by B4. Each hex digit represents four bits. BX is a synonym for B4.
|
Some examples of B4 constants are:
| 'CA'B4 | is the same as | "1100_1010"B |
| '80'B4 | is the same as | '1000_0000'B |
| '1'B4 | is the same as | '0001'B |
| (2)'F'B4 | is the same as | '1111_1111'B |
| (2)'F'B4 | is the same as | 'FF'BX |
| ''B4 | is the same as | ""B |
The B3 bit constant is a contiguous sequence of octal digits enclosed in single or double quotation marks and followed immediately by B3. Each octal digit represents three bits.
Some examples of B3 constants are:
| '22'B3 | is the same as | "010_010"B |
| '40'B3 | is the same as | '100_000'B |
| '1'B3 | is the same as | '001'B |
| (2)'7'B3 | is the same as | '111_111'B |
| ''B3 | is the same as | ""B |
GRAPHIC data can contain any DBCS character. Each DBCS character occupies 2 bytes of storage.
A graphic constant is a contiguous sequence of DBCS characters enclosed in single or double quotation marks. Graphic constants take up 2 bytes of storage for each DBCS character in the constant.
G literals can start and end with DBCS quotes; in this case, the G itself can also be specified in DBCS.
|
The GRAPHIC compiler option must be in effect for graphic constants to be accepted. If the GRAPHIC ENVIRONMENT option is not specified for STREAM I/O files that include graphic constants, the CONVERSION condition is raised.
The GX graphic constant is a contiguous sequence of hex digits, in multiples of 4, enclosed in single or double quotation marks and followed immediately by GX. Each group of 4 hex digits represents one DBCS character.
|
Examples:
Mixed character data can contain SBCS and DBCS characters. Mixed data is represented by the CHARACTER data type, and follows the processing rules for CHARACTER data.
The CHARGRAPHIC option of the OPTIONS attribute and the MPSTR built-in function can be used to assist in mixed data handling. For more information on CHARGRAPHIC see OPTIONS option and attribute; for information on MPSTR, see MPSTR.
An M constant is a contiguous sequence of DBCS and/or SBCS characters enclosed in quotation marks (single or double), followed immediately by the letter M. Quotations marks included in the constant follow the rules listed in Using quotation marks. The length of an M constant is the number of SBCS characters between the enclosing quotation marks counting any doubled quotation marks as a single character, plus twice the number of DBCS characters in the string.
A null M constant is written as two quotation marks followed by M.
|
Examples of mixed character constants are:
The GRAPHIC compiler option must be in effect for mixed constants to be accepted. If the GRAPHIC ENVIRONMENT option is not specified for STREAM I/O files having mixed constants, the CONVERSION condition is raised.
On z/OS, these additional rules apply to mixed constants:
WIDECHAR data can contain any UTF-16 character. Each widechar occupies 2 bytes of storage.
There is currently no support yet for
If you create a WIDECHAR file, you should write the endianness flag ('fe_ff'wx) as the first two bytes of the file.
The WX widechar constant is a contiguous sequence of hex digits, in multiples of 4, enclosed in single or double quotation marks and followed immediately by WX. Each group of 4 hex digits represents one UTF-16 character.
|
Examples:
A numeric character data item is the value of a variable that has been declared with the PICTURE attribute with a numeric picture specification. The data item is the character representation of a decimal fixed-point or floating-point value.
Numeric picture specification describes a character string that can be assigned only data that can be converted to an arithmetic value.
For example:
declare Price picture '999V99';
specifies that any value assigned to Price is maintained as a character string of five decimal digits, with an assumed decimal point preceding the rightmost two digits. Data assigned to Price is aligned on the assumed point in the same way that point alignment is maintained for fixed-point decimal data.
Numeric character data has arithmetic attributes, but it is not stored in coded arithmetic form. Numeric character data is stored as a character string. Before it can be used in arithmetic computations, it must be converted either to decimal fixed-point or to decimal floating-point format. Such conversions are done automatically, but they require extra processing time.
Although numeric character data is in character form, like character strings, and although it is aligned on the decimal point like coded arithmetic data, it is processed differently from the way either coded arithmetic items or character strings are processed. Editing characters can be specified for insertion into a numeric character data item, and such characters are actually stored within the data item. Consequently, when the item is printed or treated as a character string, the editing characters are included in the assignment operation. However, if a numeric character item is assigned to another numeric character or arithmetic variable, the editing characters are not included in the assignment operation--only the actual digits, signs, and the location of the assumed decimal point are assigned. For example:
declare Price picture '$99V.99',
Cost character (6),
Amount fixed decimal (6,2);
Price = 12.28;
Cost = '$12.28';
In the picture specification for PRICE, the currency symbol ($) and the decimal point (.) are editing characters. They are stored as characters in the data item. However, they are not a part of its arithmetic value. After both assignment statements are executed, the actual internal character representation of Price and Cost can be considered identical. If they were printed, they would print exactly the same; but they do not always function in the same way. For example:
Amount = Price; Cost = Price; Amount = Cost; Price = Cost;
After the first two assignment statements are executed, the value of Amount is 0012.28 and the value of Cost is '$12.28'. In the assignment of Price to Amount, the currency symbol and the decimal point are editing characters, and they are not part of the assignment. The numeric value of Price is converted to internal coded arithmetic form. In the assignment of Price to Cost, however, the assignment is to a character string, and the editing characters of a numeric picture specification always participate in such an assignment. No conversion is necessary because Price is stored in character form.
The third and fourth assignment statements would raise the CONVERSION condition. The value of Cost cannot be assigned to Amount because the currency symbol in the string makes it invalid as an arithmetic constant. The value of Cost cannot be assigned to Price for the same reason. Only values that are of arithmetic type, or that can be converted to arithmetic type, can be assigned to a variable declared with a numeric picture specification.
Although the decimal point can be an editing character or an actual character in a character string, it does not raise the CONVERSION condition in converting to arithmetic form, since its appearance is valid in an arithmetic constant. The same is true for a valid plus or minus sign, because converting to arithmetic form provides for a sign preceding an arithmetic constant.
Other editing characters, including zero suppression characters, drifting characters, and insertion characters, can be used in numeric picture specifications. For a complete discussion of picture characters, see Picture specification characters.
Implicit date comparisons and conversions are made by the compiler if the two operands have the DATE attribute. The DATE attribute specifies that a variable (or argument or returned value) holds a date with a specified pattern.
|
The DATE attribute is valid only with variables having one of the following sets of attributes:
The length or precision of n must match the length of the pattern.
When you specify the RESPECT compile-time option (see the Programming Guide for details), the following occur:
This allows DATE() to be assigned to a variable with the attribute DATE('YYMMDD') without an error message being generated. If DATE() is assigned to a variable not having the DATE attribute, however, an error message is generated.
The DATE attribute causes implicit commoning when two variables declared with the DATE attribute are compared. Comparisons where only one variable has the DATE attribute are flagged, and the other comparand is generally treated as if it had the same DATE attribute, although some exceptions apply which are discussed later.
Implicit commoning means that the compiler generates code to convert the dates to a common, comparable representation. This process converts 2-digit years using the window you specify in the WINDOW compile-time option.
In the following code fragment, if the DATE attribute is honored, then the comparison in the second display statement is 'windowed'. This means that if the window started at 1900, the comparison would return false. However, if the window started at 1950, the comparison would return true.
dcl a pic'(6)9' date;
dcl b pic'(6)9' def(a);
dcl c pic'(6)9' date;
dcl d pic'(6)9' def(c);
b = '670101';
d = '010101';
display( b || ' < ' || d || ' ?' );
display( a < c );
Date comparisons can occur in the following places:
The compiler does not generate any special code to compare dates with identical patterns under the following conditions:
For comparisons involving dates with unlike patterns, the compiler generates code to convert the dates to a common comparable representation. Once the conversion has taken place, the compiler compares the two values.
If you are making comparisons in which one comparand has the DATE attribute and the other is a literal, the compiler issues a W-level message. Further compiler action depends on the value of the literal as follows:
dcl start_date char(6) date; if start_date >= '' then /* no windowing */ ... if start_date >= '851003' then /* windowed */ ...
In comparisons where one comparand has the DATE attribute and the other is not a date and not a literal, the compiler issues an E-level message. The non-date value is treated as if it had the same date pattern as the other comparand and as if it had the same window.
dcl start_date char(6) date; dcl non_date char (6); if start_date >= non_date then /* windowed */ ...
The DATE attribute can also cause implicit conversions to occur in assignments of two variables declared with date patterns.
dcl start_date char(6) date; start_date = ''; ...
dcl x char(6) date;
dcl y char(8) date('YYYYMMDD');
y = '20600101';
x = y; /* raises error if window is <= 1960 */Even if you do not choose a windowing solution, you might have some code that needs to manipulate both two- and four-digit years. You can use multiple date patterns to help you in these situations:
dcl old_date char(6) date('YYMMDD');
dcl new_date char(8) date('YYYYMMDD');
new_date = old_date;
In PL/I, effective assignments occur when
The following uses of date variables are flagged:
In all of the cases listed previously, code is produced but no windowing occurs. In effect, the DATE attribute is ignored.
A named constant is a scalar identifier declared with the VALUE attribute along with other data attributes. All references to the name are logically treated as a reference to the appropriate constant but with the complete set of attributes, whether explicitly declared or defaulted.
Named constants can be more precise to use in an application program, and they can offer more predictable results. For example, if the named constant Unit is defined as FIXED BINARY VALUE(1), it has the attributes FIXED BINARY(15) VALUE(1). If you simply use the digit 1, its attributes are FIXED DECIMAL(1,0). See Figure 1 for other differences that can occur.
In addition, named constants allow you to parameterize your application, which makes it easier to debug and maintain.
Named constants can be declared for arithmetic data, string data, and for pointers and offsets. For arithmetic and string data and their attributes, see String data and attributes and Coded arithmetic data and attributes, respectively. A named constant must be declared before it is used.
|
Figure 1 shows named constants and the differences in attributes and precisions that can occur between named and unnamed constants.
Dcl A4 value(148) fixed bin,
C4 value(261) fixed bin,
Whole value(800) fixed bin;
Dcl Notes (4) static,
init(a4, (Whole/4), /* 148, 200 */
c4, (Whole*2)); /* 261, 1600 */
/* note that "Head" gets length equal to length of VALUE */
Dcl Head char VALUE('Feel the Power of PL/I'); /* char(22) */
Dcl Headsize fixed bin value(length(Head)); /* 22 */
Dcl 1 Head1 static,
2 * char(Headsize) initial(Head), /* char(22) */
2 * char(20) init(''),
2 * char(5) init('Page '),
2 Page_number pic 'zz9',
2 * char(0);
Dcl TwoHeads char(2*Headsize); /* char(44) */
Dcl Page0 picture 'zz9' value(0);
Dcl MyNullPtr ptr value(ptrvalue('ffff_ffff'xn));
/* Differences in attributes/results of
named and unnamed constants */
Dcl Pi float bin value (3.1416); /* is FLOAT BINARY(21) but ... */
3.1416 /* is FIXED DECIMAL(5,4) */
Dcl Unit fixed bin value(1); /* is FIXED BINARY(15) but ... */
1 /* is FIXED DECIMAL(1,0) */
1.0 /* is FIXED DECIMAL(2,1) */
1B /* is FIXED BINARY(1) */
0000_0000_0000_001B /* is FIXED BINARY(15) */
Dcl Title char(20) value('SCIDS'); /* is CHAR(20) but ... */
Dcl Title2 char value('SCIDS');/* is CHAR(5) */
'SCIDS' /* is CHAR(5) */Named constants can be used wherever a constant is required. They can also be used in restricted expressions that appear later in the program allowing evaluation of a dependent constant.
This section describes program control data and associated attributes. Use program-control data to indicate values that control the execution of your program.
A label is a label constant or the value of a label variable.
>>-LABEL--+--------------------------+------------------------->< | .-,--------------. | | V | | '-(----label-constant-+--)-'
If a list of label constants is given, the variable must always have as its value a member of that list, and the label constants in the list must be known in the block containing the label declaration. The parenthesized list of label constants can be used in a LABEL attribute specification for a label array.
A label constant is a name written as the label prefix of a statement (other than PROCEDURE, ENTRY, PACKAGE, or FORMAT) so that during execution, program-control can be transferred to that statement through a reference to it. (Statements discusses the syntax of the label prefix.) In the following line of code, for example, Abcde is a label constant.
Abcde: Miles = Speed*Hours;
The labelled statement can be executed either by normal sequential execution of instructions or by using the GO TO statement to transfer control to it from some other point in the program.
A label variable can have another label variable or a label constant assigned to it. When such an assignment is made, the environment of the source label is assigned to the target. If you declare a static array of labels to have initial values, the array is treated as nonassignable.
A label variable used in a GO TO statement must have as its value a label constant that is used in a block that is active at the time the GO TO is executed. Consider the following example:
declare Lbl_x label; Lbl_a: statement;
·
·
·
Lbl_b: statement;
·
·
·
Lbl_x = Lbl_a;
·
·
·
go to Lbl_x;
Lbl_a and Lbl_b are label constants, and Lbl_x is a label variable. By assigning Lbl_a to Lbl_x, the statement GO TO Lbl_x transfers control to the Lbl_a statement. Elsewhere, the program can contain a statement assigning Lbl_b to Lbl_x. Then, any reference to Lbl_x would be the same as a reference to Lbl_b. This value of Lbl_x is retained until another value is assigned to it.
If a label variable has an invalid value, detection of such an error is not guaranteed. In the following example, transfer is made to a particular element of the array Z based on the value of I.
go to Z(I);
·
·
·
Z(1): if X = Y then return;
·
·
·
Z(2): A = A + B + C * D;
·
·
·
Z(3): A = A + 10;If Z(2) is omitted, GO TO Z(I) when I=2 raises the ERROR condition. GO TO Z(I) when I < LBOUND(Z) or I > HBOUND(Z) causes unpredictable results if the SUBSCRIPTRANGE condition is disabled.
A format data item is a format constant or a format variable. A format constant is a name written as the label prefix of a FORMAT statement.
The FORMAT attribute specifies that the name being declared is a format variable.
|
A name declared with the FORMAT attribute can have another format variable or a format constant assigned to it. When such an assignment is made, the environment of the source label is assigned to the target.
To maintain compatibility between other PL/I compilers, format variables may be declared as label variables.
Consider the following example:
Prntexe: format
( column(20),A(15), column(40),A(15), column(60),A(15) );
Prntstf: format
( column(20),A(10), column(35),A(10), column(50),A(10) );Prntexe and Prntstf are the format constants.
A second example indicates that 4 and 5 have the same effect as 2 , and 6 and 7 have the same effect as 3 .
1 dcl Print format; 2 put edit (X,Y,Z) (R(Prntexe) ); 3 put edit (X,Y,Z) (R(Prntstf) ); 4 Print = Prntexe; 5 put edit (X,Y,Z) (R(Print) ); 6 Print = Prntstf; 7 put edit (X,Y,Z) (R(Print) );
The VARIABLE attribute establishes the name as a variable and should be specified only along with one of the attributes: ENTRY, FILE or LABEL. It will be ignored in all other declares.
|
The VARIABLE attribute is implied if the name is a member of a structure or union, or if any of the following attributes are specified:
In the following declaration, Account1 and Account2 are file variables and File1 and File2 are file constants.
declare Account1 file variable,
Account2 file automatic,
File1 file,
File2 file;
File1 and File2 can subsequently be assigned to Account1 or to Account2.