梦见好多葡萄是什么意思| 小腹痛男性什么原因| 做活检是什么意思| 晚上咳嗽什么原因| 一什么不什么| fsh是什么意思| 高锰酸钾在药店叫什么| 酚妥拉明是什么药| 为什么肚子会胀气| 天秤和什么星座最配| 为什么延迟退休| 柠檬什么时候开花结果| 车前草的作用是什么| 大便失禁是什么原因造成的| 富贵竹开花什么预兆| 菠萝和什么不能一起吃| 血压高要吃什么蔬菜能降血压| 中国最大的海是什么海| 促胃动力药什么时候吃| 劳损是什么意思| 大肠在人体什么位置图| 草字头加西念什么| 奶水不足吃什么下奶最快| 排卵期出血是什么样的| 扳机点是什么意思| 虚火吃什么药| 陶渊明字什么| 吃什么能生精和提高精子质量| 胸膜炎有什么症状| 湿疹用什么药膏好| 割包皮有什么好处和坏处| 贱人的意思是什么意思| 皂角是什么| 为什么叫黄瓜| 马夫是什么意思| 腿肿是什么原因引起的怎么办| 生菜有什么营养价值| 孕妇心情不好对胎儿有什么影响| 迅雷不及掩耳之势是什么意思| 丑未相冲的结果是什么| 七杀是什么| 肾精亏虚是什么意思| 脑供血不足什么症状| 鸡吃什么长得又快又肥| d什么意思| 什么那是什么吧| 4月6日是什么星座| 受用是什么意思| 血液由什么和什么组成| 颈椎病是什么原因引起的| 阑尾炎应该挂什么科| 内科主要看什么病| 梦到抓到鱼是什么意思| 绿对什么| 耳朵一直痒是什么原因| 用盐水洗脸有什么好处| 不经意间是什么意思| 黑头发有什么好处脑筋急转弯| 什么叫npc| 腰间盘突出有什么症状| 营养不良会导致身体出现什么症状| 10.28是什么星座| 阴道出血是什么样的| 纯牛奶可以做什么美食| 日希是什么字| 低聚糖是什么| 鱼腥草与什么相克| 运动出汗多是什么原因| 胸贴是什么| b是什么牌子的衣服| 古什么今什么| 系统性红斑狼疮是什么病| 阑尾炎吃什么药最有效| 淋巴结转移是什么意思| 三月一日是什么星座| 十一月二十二是什么星座| 日加西念什么| 57年属什么生肖| 子宫息肉有什么症状| 蟾蜍是什么动物| 维酶素片搭配什么药治萎缩性胃炎| 爱是什么词| 社会公德的主要内容是什么| 徐州二院全名叫什么| 荠菜什么时候播种最好| 知了的学名叫什么| 饮鸩止渴什么意思| 门的单位是什么| 内招是什么意思| 急性肠胃炎可以吃什么水果| 孩子胆子小用什么方法可以改变| 18k金是什么材质| 梦见输液是什么意思| 1207是什么星座| 月经不调挂什么科室| 双性恋是什么| 炒菜是什么意思| 放疗起什么作用| 蚊子最怕什么植物| 纳财适合做什么| 互联网是干什么的| 什么叫法西斯| sapphire手表什么牌子| 黑色鸟是什么鸟| 狗狗可以吃什么| 天天都需要你爱是什么歌| 骨折恢复吃什么好| 忌诸事不宜什么意思| 奈我何是什么意思| 排卵期什么时候| 茉莉花茶适合什么季节喝| 7d是什么意思| 镶牙是什么意思| 更是什么结构的字| 咳嗽咳出血是什么原因| 张郃字什么| 什么是营养| 五级士官是什么级别| 冬天怕冷夏天怕热是什么体质| 什么原因导致宫外孕| 五红汤什么时候喝最好| 吃开心果有什么好处和坏处| 什么叫肽| 朱砂是什么意思| 左什么右什么| 厄瓜多尔说什么语言| 硬度不够吃什么药| 子宫内膜厚是什么意思| 什么是电解质水| 江团鱼又叫什么鱼| 斜视手术有什么后遗症和风险| 梅毒会通过什么传染| pr过高是什么意思| 什么是复韵母| 李子什么时候成熟| 体检喝水了有什么影响| gtp什么意思| 挺舌反应是什么| 什么是断掌| 大便为什么是黑色的是什么原因| 里急后重吃什么药| 还人是什么意思| 咳必清又叫什么| 胃烧灼感是什么原因| 什么的风采| 帕金森是什么引起的| 乳腺b超挂什么科| 止血芳酸又叫什么| 孽缘是什么意思| 打喷嚏流鼻涕属于什么感冒| 黄褐斑是什么样的图片| 电信查流量打什么电话| 内眼角越揉越痒用什么眼药水| 电饼铛什么牌子好| 过誉是什么意思| 狮子属于什么科| 坐地能吸土是什么意思| 牛黄安宫丸什么时候吃最好| 小叶苦丁茶有什么作用和功效| 股骨头疼痛什么原因| ab型血可以给什么血型输血| 客车是什么车| 五行海中金是什么意思| 女性感染hpv有什么症状| 血小板偏低是什么原因| 动脉瘤是什么| 草鱼吃什么草| 凉拌什么菜好吃| 尿发黄什么原因| 邪魅是什么意思| 华丽的什么| 五味是什么| 嘴唇痒边缘痒用什么药| 肾结石吃什么食物好| 免疫球蛋白低说明什么| 安抚奶嘴什么时候开始用| 门槛什么意思| 每天早上喝一杯蜂蜜水有什么好处| 3月9日是什么星座| 女生胸部发育到什么年龄| 菊花可以和什么一起泡水喝| 坚持是什么意思| 布洛芬不能和什么一起吃| 阴道流黄水是什么原因| 煎中药用什么容器最好| 男的有霉菌是什么症状| 吃什么补血贫血| 中元节与什么生肖有关| b族维生素什么时候吃效果最好| 肺大泡是什么意思| 心率用什么字母表示| 年轮稀疏的一面是什么方向| 29度穿什么衣服合适| 身上长小肉揪是什么原因| 为什么超市大米不生虫| 谷氨酰基转移酶低是什么原因| 3个火读什么| ami是什么| 拉尼娜现象是什么| 工装裤搭配什么鞋子| 枭神夺食会发生什么| 免疫力低挂什么科| 酪朊酸钠是什么| 晚上睡觉老做梦是什么原因| 三伏贴能治什么病| 94年是什么年| 代价什么意思| 消防队属于什么单位| 无为而治是什么意思| 便秘了吃什么容易排便| 常吃南瓜子有什么好处和坏处| ye是什么意思| 什么解酒快| 天天吹空调有什么危害| 逆来顺受什么意思| 端午节应该吃什么| 吹胡子瞪眼是什么意思| 仙人板板 是什么意思| 人体最大器官是什么| loft是什么意思| 脚爆皮是什么原因| 大肠杆菌用什么药治疗效果好| 探望病人买什么水果| 南瓜什么人不能吃| 不喜欢是什么意思| 肝胆挂什么科| 氢氧化钙是什么东西| 双环征是什么意思| 肉身成圣是什么意思| 数字17代表什么意思| 视力模糊是什么原因引起的| 10个月的宝宝吃什么辅食最好| 挂帅是什么意思| 耳鸣是什么病引起的| 床榻是什么意思| 羊水穿刺检查什么| 术后吃什么刀口恢复得快| 首长是什么意思| 高血压二级是什么意思| 水疱疹什么药最快能治好| 人乳头瘤病毒33型阳性是什么意思| 葳蕤是什么意思| 什么人容易得间质瘤| 火腿是什么动物的腿| 学五行属什么| 甲类传染病指什么| 热玛吉是什么| 7月12日什么星座| 搓是什么意思| 空调外机为什么会滴水| 白带有血丝是什么情况| 胃火重口臭吃什么药好| 偶数和奇数是什么意思| 北极为什么没有企鹅| pdrn是什么| 发扬什么词语搭配| 排恶露吃什么药| 梦见穿新裤子是什么意思| 66岁生日有什么讲究| 及时是什么意思| 回笼觉是什么意思| 吃粥配什么菜| 超前点映什么意思| 衣服的英文是什么| 百度Jump to content

火猫直播哥本哈根游戏节:EHOME女队首次出征!

From Wikipedia, the free encyclopedia
百度 之后的比赛,他因为两次扭脚,也就收着打了。

The computer programming languages C and Pascal have similar times of origin, influences, and purposes. Both were used to design (and compile) their own compilers early in their lifetimes. The original Pascal definition appeared in 1969 and a first compiler in 1970. The first version of C appeared in 1972.

Both are descendants of the ALGOL language series. ALGOL introduced programming language support for structured programming, where programs are constructed of single entry and single exit constructs such as if, while, for and case. Pascal stems directly from ALGOL W, while it shared some new ideas with ALGOL 68. The C language is more indirectly related to ALGOL, originally through B, BCPL, and CPL, and later through ALGOL 68 (for example in case of struct and union) and also Pascal (for example in case of enumerations, const, typedef and Booleans). Some Pascal dialects also incorporated traits from C.

The languages documented here are the Pascal designed by Niklaus Wirth, as standardized as ISO 7185 in 1982, and the C designed by Dennis Ritchie, as standardized as C89 in 1989. The reason is that these versions both represent the mature version of the language, and also because they are comparatively close in time. ANSI C and C99 (the later C standards) features, and features of later implementations of Pascal (Turbo Pascal, Free Pascal etc.) are not included in the comparison, despite the improvements in robustness and functionality that they conferred e.g. Comparison of Pascal and Delphi

Syntax

[edit]

Syntactically, Pascal is much more ALGOL-like than C. English keywords are retained where C uses punctuation symbols – Pascal has and, or, and mod where C uses &&, ||, and % for example. However, C is more ALGOL-like than Pascal regarding (simple) declarations, retaining the type-name variable-name syntax. For example, C can accept declarations at the start of any block, not just the outer block of a function.

Semicolon use

[edit]

Another, more subtle, difference is the role of the semicolon. In Pascal, semicolons separate individual statements within a compound statement; instead in C, they terminate the statement. In C, they are also syntactically part of the statement (transforming an expression into a statement). This difference manifests mainly in two situations:

  • in Pascal, a semicolon can never be directly before else, whereas in C, it is mandatory, unless a block statement is used
  • the last statement before an end or until is not required to be followed by a semicolon

A superfluous semicolon can be put on the last line before end, thereby formally inserting an empty statement.

Comments

[edit]

In traditional C, there are only /* block comments */.

In Pascal, there are { block comments } and (* block comments *).

Identifiers and keywords

[edit]

C and Pascal differ in their interpretation of upper and lower case. C is case sensitive while Pascal is not, thus MyLabel and mylabel are distinct names in C but identical in Pascal. In both languages, identifiers consist of letters and digits, with the rule that the first character may not be a digit. In C, the underscore counts as a letter, so even _abc is a valid name. Names with a leading underscore are often used to differentiate special system identifiers in C.

Both C and Pascal use keywords (words reserved for use by the language). Examples are if, while, const, for and goto, which are keywords that happen to be common to both languages. In C, the basic built-in type names are also keywords (e.g., int, char) or combinations of keywords (e.g., unsigned char), while in Pascal the built-in type names are predefined normal identifiers.

Definitions, declarations, and blocks

[edit]

In Pascal, subroutine definitions start with keywords procedure (no value returned) or function (a value is returned) and type definitions with type. In C, all subroutines have function definitions (procedures being void functions) and type definitions use the keyword typedef. Both languages use a mix of keywords and punctuation for definitions of complex types; for instance, arrays are defined by the keyword array in Pascal and by punctuation in C, while enumerations are defined by the keyword enum in C but by punctuation in Pascal.

In Pascal subroutines, begin and end delimit a block of statements preceded by local declarations, while C functions use "{" and "}" to delimit a block of statements optionally preceded by declarations : C (before C99) strictly defines that any declarations must occur before the statements within a particular block but allows blocks to appear within blocks, which is a way to go around this. By its syntax of a subroutine's body, Pascal enforces that declarations occur before statements. Pascal also allows definitions of types and functions – not only variable declarations – to be encapsulated by function definitions to any level of depth.

Implementation

[edit]

The grammars of both languages are of a similar size. From an implementation perspective the main difference between the two languages is that to parse C it is necessary to have access to a symbol table for types, while in Pascal there is only one such construct, assignment. For instance, the C fragment X * Y; could be a declaration of Y to be an object whose type is pointer to X, or a statement-expression that multiplies X and Y. In contrast, the corresponding Pascal fragments var Y : ^X; and Z := X * Y; are inherently unambiguous; correct parsing does not require a symbol table.

Simple types

[edit]

Integers

[edit]

Pascal requires all variable and function declarations to specify their type explicitly. In traditional C, a type name may be omitted in most contexts and the default type int (which corresponds to integer in Pascal) is then implicitly assumed (however, such defaults are considered bad practice in C and are often flagged by warnings).

C accommodates different sizes and signed and unsigned modes for integers by using modifiers such as long, short, signed, unsigned, etc. The exact meaning of the resulting integer type is machine-dependent, what can be guaranteed is that long int is no shorter than int and int is no shorter than short int. However, in C standard, there are at least minimal sizes of types are specified which guarantees char to be a single byte and int to be at least two bytes.

Subranges

[edit]

In Pascal, a similar end is performed by declaring a subrange of integer (a compiler may then choose to allocate a smaller amount of storage for the declared variable):

type a = 1..100;
     b = -20..20;
     c = 0..100000;

This subrange feature is not supported by C.

A major, if subtle, difference between C and Pascal is how they promote integer operations. In Pascal, the result of an operation is defined for all integer/subrange types, even if intermediate results do not fit into an integer. The result is undefined only if it does not fit into the integer/subrange on the left hand side of the assignment. This may imply an artificial restriction on the range of integer types, or may require slow execution to handle the intermediate results: However, the compiler may take advantage of restricted subranges to produce more efficient code.

In C, operands must first be promoted to the size of the required result: intermediate results are undefined if they do not fit into the range of the promoted operands. If range of the required result is greater than the range of operands, this normally produces slow inefficient code, even from a good optimising compiler. However, a C compiler is never required or expected to handle out of range intermediate results: it is the programmers responsibility to ensure that all intermediate results fit into the operand range.

Pre-Standard implementations of C as well as Small-C et al. allowed integer and pointer types to be relatively freely intermixed.

Character types

[edit]

In C the character type is char which is a kind of integer that is no longer than short int, . Expressions such as 'x'+1 are therefore perfectly legal, as are declarations such as int i='i'; and char c=74;.

This integer nature of char (one byte) is clearly illustrated by declarations such as

unsigned char uc = 255;  /* common limit */
signed char sc = -128;   /* common negative limit */

Whether the char type should be regarded as signed or unsigned by default is up to the implementation.

In Pascal, characters and integers are distinct types. The inbuilt compiler functions ord() and chr() can be used to typecast single characters to the corresponding integer value of the character set in use, and vice versa. e.g. on systems using the ASCII character set ord('1') = 49 and chr(9) is a TAB character.

Boolean types

[edit]

In Pascal, boolean is an enumerated type. The possible values of boolean are false and true, with ordinal value of false = 0 and true = 1. For conversion to integer, ord is used:

i := ord(b);

There is no standard function for integer to boolean, however, the conversion is simple in practice:

b := i <> 0;

C has no Boolean type. C uses binary valued relational operators (<, >, ==, !=, <=, >=) which may be regarded as Boolean in the sense that they always give results that are either zero or one. As all tests (&&, ||, ?:, if, while, etc.) are performed by zero-checks, false is represented by zero, while true is represented by any other value. This is visible in the bool numeric datatype defined in stdbool.h.

Bitwise operations

[edit]

C allows using bitwise operators to perform Boolean operations. Care must be taken because the semantics are different when operands make use of more than one bit to represent a value.

Pascal has another more abstract, high-level method of dealing with bitwise data, sets. Sets allow the programmer to set, clear, intersect, and unite bitwise data values, rather than using direct bitwise operators. Example;

Pascal:

Status := Status + [StickyFlag];
Status := Status - [StickyFlag];
if (StickyFlag in Status) then ...

C:
<syntaxhighlight lang="c">
Status |= StickyFlag;
Status &= ~StickyFlag;
if (Status & StickyFlag) { ...

Although bit operations on integers and operations on sets can be considered similar if the sets are implemented using bits, there is no direct parallel between their uses unless a non-standard conversion between integers and sets is possible.

A note on implementation

[edit]

During expression evaluation, and in both languages, a Boolean value may be internally stored as a single bit, a single byte, a full machine word, a position in the generated code, or as a condition code in a status register, depending on machine, compiler, and situation; these factors are usually more important than the language compiled.

Floating point types

[edit]

C has a less strict model of floating point types than Pascal. In C, integers may be implicitly converted to floating point numbers, and vice versa (though possible precision loss may be flagged by warnings). In Pascal, integers may be implicitly converted to real, but conversion of real to integer (where information may be lost) must be done explicitly via the functions trunc() and round(), which truncate or round off the fraction, respectively.

Enumeration types

[edit]

Both C and Pascal include enumeration types. A Pascal example:

type
  color = (red, green, blue);
var
  a: color;

A C example:

enum color {red, green, blue};
enum color a;

The behavior of the types in the two languages however is very different. In Pascal enumerations are ordinal and parsed using ord(), succ() and pred() functions and are distinct from the array structure. In C, enumerations are in fact implemented as arrays and red becomes just a synonym for 0, green for 1, blue for 2, and nothing prevents a value outside this range to be assigned to the variable a. Furthermore, operations like a = a + 1; are strictly forbidden in Pascal; instead, you would use a := succ(a);. In C, enums can be freely converted to and from ints, but in Pascal, the function ord() must be used to convert from enumerated types to integers. Integers cannot be converted to enumerated types, but enumerated types can be used in statements that might otherwise use integers:

for a := red to blue do

Structured types

[edit]

Array types

[edit]

Both C and Pascal allow arrays of other complex types, including other arrays. However, there the similarity between the languages ends. C arrays are simply defined by a base type and the number of elements:

int a[SIZE];

and are always indexed from 0 up to SIZE?1 (i.e. modulo SIZE).

In Pascal, the range of indices is often specified by a subrange (as introduced under simple types above). The ten elements of

var a : array[0..9] of integer;

would be indexed by 0..9 (just as in C in this case). Array indices can be any ordinal data type, however, not just ranges:

type
   TColor = (red, green, blue);       (* enumeration *)
   RGB = array[TColor] of 0..255;

var picture : array[1..640, 1..480] of RGB

var palette : array[byte, 0..2] of byte

Strings consisting of n (>1) characters are defined as packed arrays with range 1..n.

Arrays and pointers

[edit]

In C expressions, an identifier representing an array is treated as a constant pointer to the first element of the array, thus, given the declarations int a[10] and int *p; the assignment p = a is valid and causes p and a to point to the same array. As the identifier a represents a constant address, a = p is not valid, however.

While arrays in C are fixed, pointers to them are interchangeable. This flexibility allows C to manipulate any length array using the same code. It also leaves the programmer with the responsibility not to write outside the allocated array, as no checks are built in into the language.

In Pascal, arrays are a distinct type from pointers. This makes bounds checking for arrays possible from a compiler perspective. Practically all Pascal compilers support range checking as a compile option. The ability to both have arrays that change length at runtime, and be able to check them under language control, is often termed "dynamic arrays". In Pascal the number of elements in each array type is determined at compile-time and cannot be changed during the execution of the program. Hence, it is not possible to define an array whose length depends in any way on program data.

C has the ability to initialize arrays of arbitrary length. The sizeof operator can be used to obtain the size of a statically initialized array in C code. For instance, in the following code, the terminating index for the loop automatically adjusts should the list of strings be changed.

static char *wordlist[] = {
  "print",   "out",   "the",  "text",   "message" };
static int listSize = (sizeof(wordlist)/sizeof(wordlist[0]));
int i;

for (i=0; i<listSize; i++)
  puts(wordlist[i]);
for (i=listSize-1; i>=0; i--)
  puts(wordlist[i]);

Pascal has neither array initialization (outside of the case of strings) nor a means of determining arbitrary array sizes at compile time. One way of implementing the above example in Pascal, but without the automatic size adjustment, is:

const
  minlist = 1;
  maxlist = 5;
  maxword = 7;

type
  listrange = minlist .. maxlist;
  wordrange = 1..maxword;
  word = record
    contents: packed array [wordrange] of char;
    length: wordrange
  end;
  wordlist = array[listrange] of word;
var
  i: integer;
  words: wordlist;

procedure CreateList(var w: wordlist);
begin
  w[1].contents := 'print  ';
  w[1].length := 5;
  w[2].contents := 'out    ';
  w[2].length := 3;
  w[3].contents := 'the    ';
  w[3].length := 3;
  w[4].contents := 'text   ';
  w[4].length := 4;
  w[5].contents := 'message';
  w[5].length := 7;
end;

begin
  CreateList(words);
  for i := minlist to maxlist do
    with words[i] do
      WriteLn(contents: length);
  for i := maxlist downto minlist do
    with words[i] do
      WriteLn(contents: length)
end.

Strings

[edit]

In both languages, a string is a primitive array of characters.

In Pascal a string literal of length n is compatible with the type packed array [1..n] of char. In C a string generally has the type char[n].

Pascal has no support for variable-length arrays, and so any set of routines to perform string operations is dependent on a particular string size. The now standardized Pascal "conformant array parameter" extension solves this to a great extent, and many or even most implementations of Pascal have support for strings native to the language.

C string literals are null-terminated; that is to say, a trailing null character as an end-of-string sentinel:

const char *p;
p = "the rain in Spain";     /* null-terminated */

Null-termination must be manually maintained for string variables stored in arrays (this is often partly handled by library routines).

C lacks built-in string or array assignment, so the string is not being transferred to p, but rather p is being made to point to the constant string in memory.

In Pascal, unlike C, the string's first character element is at index 1 and not 0 (leading it to be length-prefixed). This is because Pascal stores the length of the string at the 0th element of the character array. If this difference is not well understood it can lead to errors when porting or trying to interface object code generated by both languages.

FreeBSD developer Poul-Henning Kamp, writing in ACM Queue, would later refer to the victory of null-terminated strings over length-prefixed strings as "the most expensive one-byte mistake" ever.[1]

Record types

[edit]

Both C and Pascal can declare "record" types. In C, they are termed "structures".

struct a {
   int b;
   char c;
};
type a = record
   b: integer;
   c: char;
end;

In Pascal, we can use the sentence "with name_of_record do" in order to use directly the fields of that record, like local variables, instead of write name_of_record.name_of_field. Here there is an example:

type r = record
   s: string;
   c: char;
end;
var r1 : r;
begin
  with r1 do begin
    s := 'foo';
    c := 'b'
  end
end;

There is no equivalent feature to with in C.

In C, the exact bit length of a field can be specified:

struct a {
   unsigned int b:3;
   unsigned int c:1;
};

How much storage is used depends on traits (e.g., word-alignment) of the target system.

This feature is available in Pascal by using the subrange construct (3 bits gives a range from 0 to 7) in association with the keyword packed:

type a = packed record
   b: 0..7;
   c: 0..1;
end;

Both C and Pascal support records which can include different fields overlapping each other:

union a {
   int a;
   float b;
};
type a = record
   case boolean of
      false: (a: integer);
      true:  (b: real)
end;

Both language processors are free to allocate only as much space for these records as needed to contain the largest type in the union/record. In Pascal, such constructs are called variant records, not to be mistaken with the Variant datatype defined in Free Pascal.

The biggest difference between C and Pascal is that Pascal supports the explicit use of a "tagfield" for the language processor to determine if the valid component of the variant record is being accessed:

type a = record
   case q: boolean of
      false: (a: integer);
      true:  (b: real)
end;

In this case, the tag field q must be set to the right state to access the proper parts of the record.

Pointers

[edit]

In C, pointers can be made to point at most program entities, including objects or functions:

int a;
int *b;
int (*compare)(int c, int d);
int  MyCompare(int c, int d);
 
b = &a;
compare = &MyCompare;

In C, since arrays and pointers have a close equivalence, the following are the same:

a = b[5];
a = *(b+5);
a = *(5+b);
a = 5[b];

Thus, pointers are often used in C as just another method to access arrays.

To create dynamic data, the library functions malloc() and free() are used to obtain and release dynamic blocks of data. Thus, dynamic memory allocation is not built into the language processor. This is especially valuable when C is being used in operating system kernels or embedded targets as these things are very platform (not just architecture) specific and would require changing the C compiler for each platform (or operating system) that it would be used on.

Pascal has the same kind of pointers as C, through the ^ referencing operator instead of the * of C. Each pointer is bound to a single dynamic data item, and can only be moved by assignment:

type a = ^integer;

var b, c: a;

new(b);
c := b;

Pointers in Pascal are type safe; i.e. a pointer to one data type can only be assigned to a pointer of the same data type. Also pointers can never be assigned to non-pointer variables. Pointer arithmetic (a common source of programming errors in C, especially when combined with endianness issues and platform-independent type sizes) is not permitted in Pascal. All of these restrictions reduce the possibility of pointer-related errors in Pascal compared to C, but do not prevent invalid pointer references in Pascal altogether. For example, a runtime error will occur if a pointer is referenced before it has been initialized or after it has been disposed of.

Expressions

[edit]

Precedence levels

[edit]

The languages differ significantly when it comes to expression evaluation, but all-in-all they are comparable.

Pascal

  1. Logical negation: not
  2. Multiplicative: * / div mod and
  3. Additive: + - or
  4. Relational: = <> < > <= >= in

C

  1. Unary postfix: [] () . -> ++ --
  2. Unary prefix: & * + - ! ~ ++ -- (type) sizeof
  3. Multiplicative: * / %
  4. Additive: + -
  5. Shift: << >>
  6. Relational: < > <= >=
  7. Equality: == !=
  8. Bitwise and: &
  9. Bitwise xor: ^
  10. Bitwise or: |
  11. Logical and: &&
  12. Logical or: ||
  13. Conditional: ? :
  14. Assignment: = += -= *= /= %= <<= >>= &= ^= |=
  15. Comma operator: ,

Typing

[edit]

Most operators serve several purposes in Pascal, for instance, the minus sign may be used for negation, subtraction, or set difference (depending on both type and syntactical context), the >= operator may be used to compare numbers, strings, or sets, and so on. C uses dedicated operator symbols to a greater extent.

Assignment and equality tests

[edit]

The two languages use different operators for assignment. Pascal, like ALGOL, uses the mathematical equality operator = for the equality test and the symbol := for assignment, whereas C, like B, uses the mathematical equality operator for assignment. In C (and B) the == symbol of FORTRAN was chosen for the equality test.

It is a common mistake in C, due either to inexperience or to a simple typing error, to accidentally put assignment expressions in conditional statements such as if (a = 10) { ... }. The code in braces will always execute because the assignment expression a = 10 has the value 10 which is non-zero and therefore considered "true" in C; this is in part because C (and ALGOL) allow multiple assignment in the form a = b = c = 10; which is not supported by Pascal. Also note that a now has the value 10, which may affect the following code. Recent C compilers try to detect these cases and warn the user, asking for a less ambiguous syntax like if ((a=10) != 0 ) { ... }.

This kind of mistake cannot happen in Pascal, as assignments are not expressions and do not have a value: using the wrong operator will cause an unambiguous compilation error, and it's also less likely that anyone would mistake the := symbol for an equality test.

It is notable that ALGOL's conditional expression in the form z := if a > b then a else b; has an equivalent in C (the ternary operator from CPL) but not in Pascal, which will use if a > b then z:=a else z:=b;.

Implementation issues

[edit]

When Niklaus Wirth designed Pascal, the desire was to limit the number of levels of precedence (fewer parse routines, after all). So, the OR and exclusive OR operators are treated just like an Addop and processed at the level of a math expression. Similarly, the AND is treated like a Mulop and processed with Term. The precedence levels are

Level Syntax Element Operator
0 factor literal, variable
1 signed factor unary minus, NOT
2 term *, /, AND
3 expression +, -, OR

Notice that there is only ONE set of syntax rules, applying to both kinds of operators. According to this grammar, then, expressions like

     x + (y AND NOT z) / 3

are perfectly legal. And, in fact, they are, as far as the parser is concerned. Pascal does not allow the mixing of arithmetic and Boolean variables, and things like this are caught at the semantic level, when it comes time to generate code for them, rather than at the syntax level.

The authors of C took a diametrically opposite approach: they treat the operators as different, and in fact, in C there are no fewer than 15 levels. That's because C also has the operators '=', '+=' and its kin, '<<', '>>', '++', '--', etc. Although in C the arithmetic and Boolean operators are treated separately, the variables are not: a Boolean test can be made on any integer value.

Logical connectives

[edit]

In Pascal a boolean expression that relies on a particular evaluation ordering (possibly via side-effects in function calls) is, more or less, regarded as an error. The Pascal compiler has the freedom to use whatever ordering it may prefer and must always evaluate the whole expression even if the result can be determined by partial evaluation.

In C, dependence on boolean evaluation order is perfectly legal, and often systematically employed using the && and || operators together with operators such as ++, +=, the comma operator, etc. The && and || operators thereby function as combinations of logical operators and conditional statements.

Short circuit expression evaluation has been commonly considered an advantage for C because of the "evaluation problem":

var i: integer;
    a: packed array [1..10] of char;
  
  ...
  i := 1;
  while (i <= 10) and (a[i] <> 'x') do i := i+1;
  ...

This seemingly straightforward search is problematic in Pascal because the array access a[i] would be invalid for i equal to 11. There is more than one way to avoid this problem. The following example introduces a Boolean variable which indicates whether or not the target character has been found:

const
  strlen = 10;
var i: integer;
    a: packed array [1..strlen] of char;
    found: boolean;
  
  ...
  i := 1;
  found := false;
  while not found and (i <= strlen) do
    if (a[i] = 'x') then found := true else i := i+1;
  ...

The following uses a repeat statement instead:

const
  strlen = 10;
var i: integer;
    a: packed array [1..strlen] of char;
    found: boolean;
  
  ...
i := 1;
repeat 
  found := a[i] = 'x';
  if not found then inc(i);
until found or (i > strlen);
  ...

Control structures

[edit]

Statements for building control structures are similar but not equivalent.

PascalC
if cond then stmt else stmtif (cond) stmt else stmt
while cond do stmtwhile (cond) stmt
repeat stmt until conddo stmt while (cond);
for id := expr to expr do stmt
and
for id := expr downto expr do stmt
for (expr; cond; expr) stmt
case expr of
    expr : stmt;
    ...
    expr : stmt;
end
switch (expr) {
    case expr : stmt;
    ...
    case expr : stmt;
    default: stmt
}

The final value of id, the control variable, is left undefined upon normal exit from the for statement in Pascal.

Pascal does not have an equivalent to default. Pascal programmers otherwise have to guard case-statements with an expression such as: if expr not in [A..B] then default-case. At most, only one of the case statements will be executed.

C has the so-called early-out statements break and continue. They are not required and, if omitted, can result in more than one case statement being executed.

Both C and Pascal have a goto statement. However, since Pascal has nested procedures/functions, jumps can be done from an inner procedure or function to the containing one; this was commonly used to implement error recovery. C has this ability via the ANSI C setjmp and longjmp. This is equivalent, but arguably less safe, since it stores program specific information like jump addresses and stack frames in a programmer accessible structure.

Functions and procedures

[edit]

Pascal routines that return a value are called functions; routines that do not return a value are called procedures. All routines in C are called functions; C functions that do not return a value are declared with a return type of void.

Pascal procedures are considered equivalent to C "void" functions, and Pascal functions are equivalent to C functions that return a value.

The following two declarations in C:

int f(int x, int y);
void k(int q);

are equivalent to the following declarations in Pascal:

function f(x, y: integer): integer;
procedure k(q: integer);

Pascal functions can only be used in an expression, whereas a C function that returns a value can be called in the same way as a "void" function and its return value ignored.

Pascal has two different types of parameters: pass-by-value, and pass-by-reference (VAR). In both cases the variable name is used when calling (no need of address operator).

function f(z: integer; var k: integer): integer; // function accepts two integers, one by value, one by reference
Begin
  z:=1; // outer variable u will not be modified, but local value is modified in the function's scope
  k:=1; // outer variable t will be modified because it was passed by reference
  // up to here, z exists and equals 1
End;

x := f(u,t); // the variables u and t are passed to the call : the value of u and the reference to t

In C all parameters are passed by value but pass-by-reference can be simulated using pointers. The following segment is similar to the Pascal segment above:

int f(int z, int *k) { //function accepts an int (by value) and a pointer to int (also by value) as parameter
  z=1;  // idem Pascal, local value is modified but outer u will not be modified
  *k=1; // variable referenced by k (eg, t) will be modified
  // up to here, z exists and equals 1
}

x = f(u,&t); // the value of u and the (value of) address of variable t are passed to the call

One of the most important difference between C and Pascal is the way they handle the parameters on stack during a subroutine call : This is called the calling convention : PASCAL-style parameters are pushed on the stack in left-to-right order. The STDCALL calling convention of C pushes the parameters on the stack in right-to-left order.

Pascal-style procedure call is made with :

  • caller pushing parameters into the stack in left-to-right order (opposite of __cdecl)
  • calling the function
  • stack is cleaned up by the callee
    ; example of pascal-style call.
    ; NOTE: __stdcall would push the arguments in reverse order.
    push arg1
    push arg2
    push arg3
    call function
    ; no stack cleanup upon return: callee did it

The advantage of PASCAL call over STDCALL is that the code is slightly smaller, though the size impact is only visible in large programs, and that recursion works faster.

C allows for functions to accept a variable number of parameters, known as variadic functions, using a clumsy mechanism of va_list ap;, va_start(ap, count);, va_arg(ap, type); with limited type availability (example : nothing for bool)

int f(int a, ...);
f(1, 2, 3, 4, 5);

The function f() uses a special set of functions (varargs) that allow it to access each of the parameters in turn.

Pascal and C also have some variadic I/O functions, for instance WriteLn() and printf().

Pascal allows procedures and functions to be nested. This is convenient to allow variables that are local to a group of procedures, but not global. C lacks this feature and the localization of variables or functions can be done only for a compiling module wherein the variables or functions would have been declared static.

C allows functions to be indirectly invoked through a function pointer. In the following example, the statement (*cmpar)(s1, s2) is equivalent to strcmp(s1, s2):

#include <string.h>

int (*cmpar)(const char *a, const char *b);
const char *s1 = "hello";
const char *s2 = "world";

cmpar = &strcmp;
b = (*cmpar)(s1, s2);

In Pascal functions and procedures can be passed as parameters to functions or procedures:

procedure ShowHex(i: integer);
...
end;

procedure ShowInt(i: integer);
...
end;

procedure Demo(procedure Show(i: integer));
var j: integer;
begin
  Show(j)
end;

...
  Demo(ShowHex);
  Demo(ShowInt);
...

Preprocessor

[edit]

Early C had neither constant declarations nor type declarations, and the C language was originally defined as needing a "preprocessor"; a separate program, and pass, that handled constant, include and macro definitions, to keep memory usage down. Later, with ANSI C, it obtained constant and type definitions features and the preprocessor also became part of the language, leading to the syntax we see today.

Pascal constant and type defines are built in and don't need a preprocessor. There were programmers using a preprocessor also with Pascal (sometimes the same one used with C), certainly not as common as with C. Although often pointed out as a "lack" in Pascal, technically C does not have program modularity nor macros built in either. It has a simple low level separate compilation facility, however (traditionally using the same generic linker used for assembly language), Pascal does not.

Type escapes

[edit]

In C, the programmer may inspect the byte-level representation of any object by pointing a char pointer to it:

int a;
char *p = (char *)(&a);
char c = *p;  // first byte of a

It may be possible to do something similar in Pascal using an undiscriminated variant record:

var a: integer;
    b: real;
    a2c: record
           case boolean of
             false: (a: integer);
             true:  (b: real);
           end;
         end;
begin
  a2c.b := b;
  a := a2c.a;
end;

Although casting is possible on most Pascal compilers and interpreters, even in the code above a2c.a and a2c.b are not required by any Pascal standardizations to share the same address space. Niklaus Wirth, the designer of Pascal, has written about the problematic nature of attempting type escapes using this approach:

"Most implementors of Pascal decided that this checking would be too expensive, enlarging code and deteriorating program efficiency. As a consequence, the variant record became a favourite feature to breach the type system by all programmers in love with tricks, which usually turn into pitfalls and calamities".

Several languages now specifically exclude such type escapes, for example Java, C# and Wirth's own Oberon.

Files

[edit]

In C files do not exist as a built-in type (they are defined in a system header) and all I/O takes place via library calls. Pascal has file handling built into the language.

The typical statements used to perform I/O in each language are:

printf("The sum is: %d\n", x);
writeln('The sum is: ', x);

The main difference is that C uses a "format string" that is interpreted to find the arguments to the printf function and convert them, whereas Pascal performs that under the control of the language processor. The Pascal method is arguably faster, because no interpretation takes place, but the C method is highly extensible.

Later Pascal implementations and extensions

[edit]

Some popular Pascal implementations have incorporated virtually all C constructs into Pascal. Examples include type casts,[2] being able to obtain the address of any variable, local or global, and different types of integers with special promotion properties.

However, the incorporation of C's lenient attitude towards types and type conversions can result in a Pascal that loses some or all of its type security. For example, Java and C# were created in part to address some of the perceived type security issues of C, and have "managed" pointers that cannot be used to create invalid references. In its original form (as described by Niklaus Wirth), Pascal qualifies as a managed pointer language, some 30 years before either Java or C#. However, a Pascal amalgamated with C would lose that protection by definition. In general, the lower dependence on pointers for basic tasks makes it safer than C in practice.

The Extended Pascal standard extends Pascal to support many things C supports, which the original standard Pascal did not, in a type safer manner. For example, schema types support (besides other uses) variable-length arrays while keeping the type-safety of mandatory carrying the array dimension with the array, allowing automatic run-time checks for out-of-range indices also for dynamically sized arrays.

See also

[edit]

Notes

[edit]
  1. ^ Kamp, Poul-Henning (25 July 2011), "The Most Expensive One-byte Mistake", ACM Queue, 9 (7): 40–43, doi:10.1145/2001562.2010365, ISSN 1542-7730, S2CID 30282393
  2. ^ "Typecast - Lazarus wiki". wiki.freepascal.org. Retrieved 2025-08-06.

Further reading

[edit]
户籍地是什么 daily是什么意思 数位板是什么 阵容是什么意思 胃反流有什么症状
蹂躏是什么意思 肚子胀疼是什么原因 保胎是什么意思 大便陶土色是什么颜色 何首乌长什么样子
胆结石有什么症状 糖类抗原153偏高是什么原因 中指和无名指发麻是什么原因 沙土地适合种什么农作物 火气重吃什么降火
薄荷叶泡水喝有什么功效和作用 什么是西米 月经先期是什么意思 破屋什么意思 什么人不能喝石斛
总胆红素高是什么意思hcv9jop5ns6r.cn out什么意思hcv8jop1ns5r.cn 初中老师需要什么学历hcv8jop1ns0r.cn 印度是什么教hcv9jop6ns8r.cn 专科考研需要什么条件hcv9jop8ns1r.cn
脾脏是人体的什么器官hcv9jop1ns8r.cn 旗舰店是什么意思hcv9jop5ns7r.cn 今天中国什么节日fenrenren.com 夏吃姜有什么好处hcv9jop1ns4r.cn 为什么老是便秘tiangongnft.com
配偶什么意思hcv9jop6ns6r.cn 血小板减少是什么原因造成的hcv8jop2ns5r.cn 皮内瘤变到底是什么意思hcv9jop1ns2r.cn 子宫痒是什么原因hcv7jop6ns5r.cn 国代是什么意思hcv9jop6ns8r.cn
鼻基底填充用什么材料比较好hcv9jop1ns1r.cn 为什么会水肿hcv9jop1ns3r.cn 心口窝疼挂什么科hcv9jop8ns1r.cn 苏小小属什么生肖hcv8jop1ns9r.cn 什么是绩效工资hcv8jop2ns9r.cn
百度