C语言程序的构成

更新时间:2024-02-02 01:57:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

章 C语言程序的构成

与C++、Java相比,C语言其实很简单,但却非常重要。因为它是C++、Java的基础。不把C语言基础打扎实,很难成为程序员高手。

一、C语言的结构

先通过一个简单的例子,把C语言的基础打牢。

/* clang01_1.c */ #include

int main(void) {

printf(\这是劝学网的C语言教程。\\n\);

return 0;

}

C语言的结构要掌握以下几点:

? C语言的注释是/* ··· */,而不是//···,//是C++的单行注释,有的C语言版本也认可。

? C语言区分大小写,每句以分号结尾。

? C语言程序是从main函数开始的。函数的返回值如果缺省则为int,而不是void。 ? 函数必须用return来返回。即使void类型也不建议省略。

? 使用函数时须包含相应的头文件。自定义的头文件用双引号,C语言自身的头文件用<···>

二、main()函数的写法与含义

main()的参数和返回值全部省略,这和上例含义相同。省略写法是一种很不好的习惯。

main() int main(void) { { ··· 等同于 ··· } }

main()的参数是一种不限个数的写法,argc代表参数的

个数,真正的参数是放在argv[]数组里面的。注意:当数组当参数用时,数组被降格为指针。初学者先照着样子写,以后小雅会详细说明指针和数组的区别。

int main(int argc, char *argv[]) int main(int argc, char **argv)

{ { ··· 也可写成 ··· } }

三、头文件的意义

每个C程序通常分为两个文件。一个文件用于保存程序的声明(declaration),称为头文件。另一个文件用于保存程序的实现(implementation),称为定义(definition)文件。 C程序的头文件以“.h”为后缀,C 程序的定义文件以“.c”为后缀。

头文件的内容也可以直接写C程序中,但这是很不好的习惯。许多初学者用了头文件,却不明其理。在此略作说明。

? 通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来

调用库功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。

? 头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。

关于头文件的内容,初学者还必须注意。

? 头文件中可以和C程序一样引用其它头文件,可以写预处理块,但不能写语句命令。

? 可以申明函数,但不可以定义函数。 ?? 可以申明常量,但不可以定义变量。

?? 可以“定义”一个宏函数。注意:宏函数很象函数,但却不是函数。其实还是一个申明。

?? 结构的定义、自定义数据类型一般也放在头文件中。

?? #include ,编译系统会到C语言固定目录去引用。#include \,系统一般首先在当前目录查找,然后再去环境指定目录查找。

四、好的风格是成功的关键

版本申明、函数功能说明、注释等是C语言程序的一部分。不养成很好的习惯则不能成为C语言高手(专业人员)。

02章 C语言的变量和数据类

掌握变量的有效范围、基本数据类型是本章的内容。

一、基本数据类型

基本数据类型只有5种,另外加上布尔型、数组、结构类型、枚举类型等都是基本类型的一种变化。指针是一种地址操作, 必须和某一种数据类型相结合才有意义。自定义数据类型则是将以上类型进行组合变化后重新命名而已。

? ? ? ? ?

char 字符型 int 整型 float 浮点型

double 双精度浮点型 void 无类型

不同的C语言版本都扩充了许多自己的类型,这些全是基本类型的变化(主要是数据范围的变化),扩充的修饰

符有2组(short和long,signed和unsigned)。下面列出VC的基本类型及部分扩充类型,以供参考: 类型名称 int

字节数 *

其它称呼 signed, signed int unsigned char,

signed char short, short int,

signed short int signed, signed int none signed char none

short int,

signed short int unsigned short int

long int,

signed long int unsigned long

根据操作系统而定 根据操作系统而定 -128 to 127 -32,768 to 32,767

-2,147,483,648 to 2,147,483,647 -9,223,372,036,854,775,808 9,223,372,036,854,775,807 -128 to 127 0 to 255 -32,768 to 32,767 0 to 65,535

-2,147,483,648 to 2,147,483,647 0 to 4,294,967,295

值的范围

unsigned int * __int8 __int16 __int32 __int64 char unsigned char short unsigned short long unsigned

1 2 4 8 1 1 2 2 4 4

long enum float double

long double

* 4 8 10

int none none none none

与int相同

3.4E +/- 38 (7 digits) 1.7E +/- 308 (15 digits) 1.2E +/- 4932 (19 digits)

标准ANSI C中没有布尔型,只有布尔表达式,但不同的C语言版本有可能扩充。布尔型只有2个值“真”、“假”,数值0表示“假”,0以外数值全当作“真”处理。

二、变量定义

变量定义要注意以下几方面:

? 变量定义必须有一数据类型。

? 变量定义时可以赋初值,也可以不赋初值。 ? 几个变量可以同时定义。

? 不同类型的变量赋值时,小类型的变量可以直接赋给大的,大类型的变量赋给小类型的变量时必须强制转换。

.NET的编译器做了许多防错处理,使得不强制转换也不出问题。大家仍不可忘记类型转换,否则将来程序移植时会带来许多麻烦。

#include

int main(void) {

unsigned char u_char = 109; //定义并初始化 char charC; //只定义不赋值 double doubleX=200, doubleY; //2变量同时定义

charC = u_char; //类型的范围相同,无须强制转换

printf(\, u_char); printf(\, charC); printf(\, u_char); printf(\, charC);

doubleY = charC; //小类型->大类型

charC = (char)doubleX; //大类型->小类型

printf(\, doubleY); printf(\, charC);

return 0; }

三、变量命名

C语言的变量命名是很自由的,不同的系统有各自的规则,如UNIX主张用小写并用下划线分割意思(例:new_value)。Windows主张大小写混写(例:NewValue)。中国主张尽可能用英文,而日本更喜欢用汉字的读音。甚至不同企业的命名规则也不一样,但不管什么风格,都必须遵守C语言的几点规则。

?? 不能用纯数字命名,如“123”,“849”等。 ?? 不能有空格和运算符,如“new value”,“two+three”。 ?? 不能用C语言的关键字(参见下表)、扩充关键字。

double int struct else long switch enum register typedef extern return union float short unsigned

auto

break case char const

continue default do

for goto if signed sizeof static void volatile while

四、易忽视的地方

char型和unsigned int是同一类型,字符其实就是无符号整型,因此下面几种写法实际上是一样的。

#include

int main(void) {

char ch1 = 109; __int8 x1 = 109;

char ch2 = 'm'; unsigned int x2 = 'm';

printf(\, ch1); //字符方式输出 printf(\, ch1); //整型方式输出

printf(\, x1); //字符方式输出 printf(\, x1); //整型方式输出

printf(\, ch2); //字符方式输出 printf(\, ch2); //整型方式输出

printf(\, x2); //字符方式输出 printf(\, x2); //整型方式输出

return 0; }

注意:字符用单引号,而以后学的字符串是用双引号的。

03章 字符的输入输出

前2章用到的printf()函数,是C语言中的带格式的标准输出函数。C语言的函数都封装在不同的函数库里面,编程时要用到某个函数时, 只要用include语句申明一下,被申明过的函数库中的所有函数就可以在程序的任何地方使用。这2章要讲述的基本输入输出函数,都 在stdio.h中被定义。

一、字符的输入输出『getchar(),putchar()』

函数getch()是从终端输入一个字符。注意:是一个字符,也就是说,该函数调用一次只能得到一个字符,想要得到若干字符,只能调用若干次。

函数putchar()是向终端输出一个字符。注意:这儿也是一个字符,也就是说,该函数调用一次只能输出一个字符,要输出若干字符,只能调用若干次。

#include

int main(void) {

char ich1; int ich2,ich3;

char ch1 = 'q'; char ch2 = 'u'; char ch3 = 'a'; char ch4 = 'n';

ich1 = getchar(); //字符类型实际是整型,只是范围小点而已

ich2 = getchar(); //所以字符赋给整数变量没有关系 ich3 = getchar(); //这三句在屏幕上输入“xue”后回车

putchar(ch1); putchar(ch2); putchar(ch3); putchar(ch4); putchar(ich1); putchar(ich2); putchar(ich3);

putchar('\\n'); //这是回车字符

return 0; }

上例中调用了3次getchar()函数,输入时请注意: ? 如果正好输入3个字符后回车,则3个字符分别赋给了相应的三个变量。

? 如果输入的字符数大干3个,则多余的被会扔掉。 ? 如果输入2个字符后回车,则回车符被赋给了第3个变量。

? 如果输入1个字符后回车,则第1个变量得到了这个字符,而第 2个变量则得到的是回车,第3个变量还没有得到,所以系统还在继续等待你输入第3个字符。 ? 如果不输入而直接敲回车,则你必须敲3次回车,3个变量全等于回车。

? getchar()的返回值不是char,而是int。因此当得到超出char范围的数据时要注意。

二、改进后的字符输入函数

上面这些令人不满的地方,主要是由于getchar()函数使用了键盘缓冲区,一直等到有回车时,getchar()函数才接受字符。因此有人对此函数进行了扩充, 函数名为getche(),不再使用键盘缓冲,输入的字符立即就能被接受。这个函数不是存放在stdio.h中,而是存放在conio.h中。上

面程序如下修改便好用多了。类似函数还有很多,如getch(),这和getche()的区别是,getch()函数在输入后并不显示在屏幕上,其它功能和getche()相同,也是定义在conio.h中。

#include #include

int main(void) {

char ich1; int ich2,ich3;

char ch1 = 'q'; char ch2 = 'u'; char ch3 = 'a'; char ch4 = 'n';

ich1 = getche(); //改进后的字符输入函数 ich2 = getche(); ich3 = getche();

putchar('\\n'); //这是回车字符 putchar(ch1); putchar(ch2); putchar(ch3); putchar(ch4); putchar(ich1); putchar(ich2); putchar(ich3);

putchar('\\n'); //这是回车字符

return 0; }

三、转义字符

前面的例子中,我们已经看很多“\\n”,它表示输出时显示一个回车。回车字符是控制字符,无法输入在字符串中间。因此,C语言用“转义字符” 来代替这一类的控制字符。注意:%的输出并不是用“\\%”表示,而是用“%%”表示,好

象就这一个是特殊的。

字符形式

\\0 \\n \\t \\v \\b \\r \\f \\\\ \\' \\\\\a \\? %% \\ddd \\xhh

功 能

空字符(NULL) 换行

横向跳格(Tab) 竖向跳格(|) 退格 回车

换页字符

反斜杠\字符 单引号(撇号)字符 双引号字符 响铃字符 问号字符 百分号字符

1~3位8进制数所代表的字符 1~2位16进制数所代表的字符

04章 附带格式的输入输出

printf()函数和scanf()函数中的f是format的缩写,这里面用到的“格式”,在C语言其它地方也有很广的应用。

一、格式输出『printf()』

前面已经说过,一个字符用%d格式就可以输出其ASCII码即字符的整数值。用%c格式则输出这个字符。如果用%f格式,则小数的方式输出。

#include

int main(void) {

int days = 360;

//“劝学网”三字的ASCII码是“C8B0”“D1A7”“CDF8” printf(\小雅\\n\); //显示:劝学网{TAB}小雅

printf(\北京奥运还有: %d天\\n\ printf(\); //“嘟嘟”

//以下三行写在同一行 printf(\这是C语言\); printf(\教程\\t\);

printf(\作者:%s\\n\小雅\);

//360分别以整数、小数、科学计数法显示 printf(\

:%d\\n

:%f\\n

学:%e\\n\,days,(float)days,(double)days);

//以下控制字节长度

printf(\用5个字节表示:[]]\\n\,days); //[...]中共5字节

printf(\保留2位整数2位小数:[%5.2f]\\n\,(float)days/100); //[...]中2位整数2位小数,

//外加小数点共5字节 return 0; }

注意:格式符的个数必须和逗号后面的变量或常量相

同,类型也必须一致或可以直接转换。

二、常见格式符号

格式字符 c C d i o u x X e E f g G n

类 型 int 或 win_t int 或 win_t int int int int int int double double double

以字符方式输出。

输出格式

用在printf()函数中时,以双字节字符显示;用在wpr以单字节字符显示。 以整型输出。 以整型输出。

以八进制无符号整型输出。 以无符号整型输出

以十六进制小写输出(abcdef)。 以十六进制小写输出(ABCDEF)。

以科学计数法表示float和double型数据。(其中e用以科学计数法表示float和double型数据。(其中E用以小数表示float和double型数据。

自动地将能显示的很小或很大的数转换成%f,不能

double

则转换成%e。

自动地将能显示的很小或很大的数转换成%f,不能

double

则转换成%E。

Number of characters successfully written so far to

Pointer to

buffer; this value is stored in the integer whose addres

integer

argument.

p s Pointer to

内存地址,以十六进制表示。

void String 以字符串输出。

用在printf()函数中时,以双字节字符串显示;用在

S

String

时,以单字节字符串显示。

三、格式输入『scanf()』

scanf()函数的功能与printf()函数正好相反,是输入数据的功能。但对于初学者却有一难点,即所输入的数据存放到变量时,用到了地址操作。地址操作也就是指针,是C语言的难点、重点,许多人不会C语言的根本原因就是没学会指针。

既然指针这么难,为什么C语言要使用指针呢?C语言产生之前,前辈们都是用机器语言或汇编语言来编程,整天都是与内存地址打交道,C语言使用了指针,使得程序运行速度接近汇编语言,编程效率、实现的功能大大提高。当今电脑硬件的飞速发展,使速度不成问题,于是Java、C#都基本废除了指针的使用。

#include

int main(void) {

int age; //年龄 char name[20]; //姓名

printf(\请输入你的年龄:\);

scanf(\, &age); //&age表示变量age的地址

printf(\请输入你的姓名:\);

scanf(\, name); //name单独使用就表示变量name的地址

printf(\姓名=%s\\t年龄=%d\\n\,name,age);

return 0;

}

上例中,2个变量当作参数使用时,一个用了&符号,一个没用,为什么呢?原来当一个变量的类型是基本类型、或扩充基本类型时,变量的地址要用&符号再加变量名。其它尤其指数组,单独使用变量名,就表示该变量的地址。关于这一点,以后讲完数组和指针后还要详细讨论。

05章 if语句和switch语句

一、if语句

在计算机如此普及的今天,if语句的功能介绍就不说了。其基本语法如下:

//写法一 if (条件表达式) { 语句 } //写法二 if (条件表达式) { 语句

} else { 语句 } //写法三 if (条件表达式) { 语句 }

else if (条件表达式) { //else if (条件表达式){语句}部分可重复n遍 语句 } else { 语句 }

else块只能出现在if语法的最后,且最多只能出现1次。else if块能出现若干次,但只能在if块的后面,不能在else块的前面。当各块里面的语句只有一句时,括号{}可以省略。不建议省略,因为省略后下面的语句让人容易糊涂。

//易让人看错的写法 //表示的是下面的意思

if (x == 1) if (x == 1) {

if (y == 1) if (y == 1) printf(\

y

1\

printf(\和y都等于1\

else else printf(\

y==1

else\

printf(\我其实是y==1的else\

}

二、switch语句

switch语句完全可以用if语句代替,每一个case块的最后一句语句要有break语句,否则将运行到下一个case块中去。还需要注意的是,switch语句只适用于基本类型的变量作条件(包括扩充基本类型)。default块可以省略,但小雅建议您不要省略,即使不用也加上。

//基本类型的变量 //假定int i; //假定char str[];以下是错误的

switch (变量) { switch (i) { switch (str) {

case 表达式1: case 1: case \

语句 语句 语句

break; break; break;

case 表达式2: case 2: case \

语句 语句 语句

break; break; break;

··· ··· ···

case 表达式n: case 10: case \

语句 语句 语句

break; break; break;

default: default: default:

语句 语句 语句

break; break; break;

} } }

三、( ? :)运算符

(表达式 ? 值1 :值2)这是带运算符的表达式,意思是:如果“表达式”的值为“真”,则返回“值1”,否则返回“值2”。if是控制语句而不是运算符,也不是表达式。

y = (x==2 ? 100 : 50) ;

//写成如下相同功能的if语句 if (x == 2) { y = 100; } else { y = 50; }

四、关于逻辑表达式

逻辑表达式又叫布尔表达式,前面章节已经说过,布尔表达式只有2个值:TRUE和FALSE,即“真”和“假”。这其实是整型,0代表FALSE,0以外全是TRUE。因此逻辑表达式的写法就变得眼花潦乱。

//x不等于0时为true //同样的写法

if (x) { if (x != 0) { y = 100 ; y = 100 ; } } else { else { y = 50 ; y = 50 ; } }

//x等于0时为true //同样的写法 //少写=,意义就不一样了

if (!x) { if (x == 0) { if (x = 0) { //将0赋给x

y = 100 ; y = 100 ; y = 100 ; //不可能运行这一句

} } } else { else { else { y = 50 ; y = 50 ; y = 50 ;

} } }

06章 while语句

一、while语句和do...while语句的比

while语句是先判断条件为“真”时才循环,do...while语句是先进入循环再判断条件为“假”来决定是否终止循环。

int i, sum=0; int i, sum=0;

scanf(\ scanf(\while (i <= 10) { do {

sum = sum + i ; sum = sum + i ; i++; i++; } } while (i <= 10) ;

当输入小于等于10的数时,两个结果完全一样,当输入大于10的数时,左边结果为0,右边结果为输入的数。说明左边未进入循环,而右边循环了一次。

二、break语句和continue语句

当运行到break语句或continue语句时,其后面的语句都不再运行。但不同的是:break语句中止了循环,从循环后面的语句开始运行;而continue语句并不中止循环,而是跳到循环的头部开始下一轮循环。

#include

int main(void) {

int i, sum=0;

while (1) {

scanf(\, &i);

if (i > 10 || i < 0) {

printf(\请输入小于10的正数\\n\); continue; }

else if (i == 0) {

printf(\退出循环\\n\);

break ; }

sum = 0; do {

sum = sum + i ; i--; } while(i > 0);

printf(\, sum); }

return 0; }

三、goto语句

goto语句的使用危险性很大,一般不建议使用,但在多重循环的情况下,要终止到指定的某一层循环时,用goto的确很省事。使用goto语句要注意以下几点,否则编译并不一定出错,但程序很危险。下面的例子就很危险。

? 不能跨函数跳转。

? 只能从块内向块外跳转,不能从块外跳到块内。

#include

int main(void) {

int x, y; scanf(\, &x); scanf(\, &y); if (x == 0) {

printf(\);

goto LA1; //这是很危险的做法 }

if (y == 100) { LA1:

printf(\); }

return 0; }

07章 for语句

while语句中说到的break语句、continue语句、goto语句等在for语句中仍然适用,这里就不再重复。本章以例子说明各种各样的for循环。

一、基本for循环

//这是标准的for循环例子 #include

int main(void) { int i;

for (i = 0; i < 3; i++) { printf(\, i); }

printf(\, i);

return 0; }

二、死循环的写法

//在循环体内控制终止条件 #include

int main(void) {

int i = 3 ; for ( ; ; ) {

printf(\, i--) ;

if (i == 0) break ; }

return 0; }

三、初始值、终止值、增量的不同写法

#include #include

int main(void) {

char ch;

//注意:循环体内一句也没有写 for (ch = getche(); ch != 'q'; ch = getche()) ;

printf(\你输入了q字符。\\n\);

return 0; }

四、九九乘法表例子

#include

int main(void) {

int i, j ;

for ( i = 1; i < 10; i++ ) { for ( j = 1; j <= i; j++ ) {

printf(\%d=- \, i, j, i * j);

}

printf(\); }

return 0; }

08章 比较、逻辑、位运算符

一、运算符的优先级

优先 运算符 () [ ] 1

含义 圆括号 下标符

结构体运算对象个数 结合方向

左→右

-> . ! ~ ++ -- 2

-

(类型) * & sizeof * 3

/ % 4

+ - 5

<< >> < 6 > >=

结构体运算符 逻辑非 位取反 增1 减1 负号

类型转换 指针 地址

类型长度 乘 除 余 加 减 位左移 位右移 比较符

单目 双目 双目 双目

双目 左←右

左→右

左→右 左→右

左→右

7

8 9 10 11 12 13

14

15

<= == !== & ^ | && || ? :

=,+=,-= *=,/=,%= >>=,<<=, &=,^=,|= ,

比较符 位与 位与或 位或 逻辑与 逻辑或 逻辑与 赋值

双目 双目 双目 双目 双目 双目 三目 双目

左→右 左→右 左→右 左→右 左→右 左→右 左←右 左←右

顺序求值符 左→右

二、比较、逻辑、位运算符

只有类型相同(或C语言能自动转换)的表达式才能比较,如果类型不同就必须用函数转换。例如:判断一字符串的长度是否等于10,就要用strlen()将字符串的长度求出来变成了整型,才能和10比较。

比较运算符只有6个,即:等于(==)、不等于(!=)、大于(>)、小于(<)、大于等于(>=)、小于等于(<=)。比较运算符也叫关系运算符。

逻辑运算符只有3个,即:与AND(&&)、或OR(||)、非NOT(!)。

位运算符只有6个,即:与AND(&)、或OR(|)、非NOT(~)、异或XOR(^)、左移ShiftLeft(<<)、右移ShiftRight(>>)。

#include

int main(void) {

//全部为1字节的变量,实际运算是4字节 unsigned char i, j, k1, k2, k3 ;

i = 0x5A; // 0101 1010 --5A

j = 0x9B; // 1001 1011 --9B k1 = ~i; // 1010 0101 --A5 k2 = i << 2; //(01)0110 1000 --68 k3 = j >> 2; // 0010 0110(11)--26

printf(\与运算 :5A & 9B = %X\\n\,i & j); //1A printf(\或运算 :5A | 9B = %X\\n\,i | j); //DB printf(\异或运算:5A ^ 9B = %X\\n\,i ^ j); //C1 printf(\取反运算:~5A = %X\\n\, k1); //A5 printf(\左移2位 :5A << 2 = %X\\n\,k2); //68 printf(\右移2位 :9B >> 2 = %X\\n\,k3); //26

//注意:这儿验证参与运算的实际结果不是1字节,而是4字节

printf(\取反运算:~5A = %X\\n\, ~i); //FFFF FFA5

printf(\左移2位 :5A << 2 = %X\\n\,i << 2); //0000 0168 printf(\右移2位 :9B >> 2 = %X\\n\,j >> 2); //0000 0026

return 0; }

三、其它运算符

一些常用易错的运算符要注意。

? 逗号(,)运算符,将几个内容合成一个运算,且不改变分开运行的结果。for语句中常用。

? i++和++i单独使用时功能相同,赋值时有先后问题。

? 赋值语句可以连续赋值,但不建议过多过杂。

#include

int main(void) {

unsigned char i, j, k1, k2, k3 ;

//逗号,运算符 i = 15, j = 19;

k1 = (12, 23, i, j); //将12,23,i,j分别赋值给k1,最后j

printf(\, k1); printf(\);

//增1运算符

k2 = i++; //k2=15, i=16 先赋值后加 k3 = ++j; //k3=20, j=20 先加后赋值 printf(\ k2 = %d\\n\, i, k2); printf(\ k3 = %d\\n\, j, k3); printf(\);

//赋值运算符

printf(\赋值前:i=%d j=%d k1=%d k2=%d k3=%d\\n\, i, j, k1, k2, k3);

i = j = k1 = k2 = k3; //自右向左,将k3分别赋给k2,k1,j,i

printf(\赋值后:i=%d j=%d k1=%d k2=%d

k3=%d\\n\, i, j, k1, k2, k3);

return 0; }

09章 数组

一、数组的定义和赋值

C语言教程中,数组是重点、难点,许多人其实是一知半解,小雅建议还未上路的人,认真阅读本章内容。下面先举例再说明。

#include

int main(void) {

int i; int iArr[7];

char cArr[] = {'Q','U','A','N','X','U','E'};

//给iArr数组赋值 for (i=0; i<7; i++) {

iArr[i] = (i + 1) * (i + 1); }

//输出iArr的内容 for

(i=0;

i<7;

i++)

printf(\

-\,

iArr[i]);

printf(\);

//输出cArr的内容

for (i=0; i<7; i++) printf(\ ,\, cArr[i]); printf(\);

//输出超出数组范围内容。该行运行时会出错。 printf(\ cArr[7]=[%c]\\n\, iArr[7]);

return 0; }

? 数组名也是一变量名,定义时须指定类型和长度。 ? 长度可以方括号中直接指定,也可以通过赋值来间接指定。

? 数组可以在定义时直接赋值,也可以定义时不赋值,之后再赋值。

? 当使用超出范围的值时,编译不出错,但运行会出

错。(上例运行时出错后,选“忽略”后得到的结果)

二、数组的地址

弄清数组地址对使用数组有很大好处,另外,有的函数的参数是指针(如scanf函数),如果要用数组的某一元素作参数,就必须知道其地址。

#include

int main(void) {

int i; int iArr[7];

char cArr[] = {'Q','U','A','N','X','U','E'};

//输出iArr数组和cArr数组的地址 printf(\, iArr, cArr);

//输出iArr[i]数组和cArr[i]数组的地址 for (i=0; i<7; i++) {

printf(\cArr[%d]=%p\\n\, i, &iArr[i], i, &cArr[i]); }

return 0; }

? 数组iArr是int类型,所以它的地址是按4字节递增。 ? 数组cArr是char类型,所以它的地址是按1字节递增。

? 数组元素的地址是通过数组元素前面加“&”来取得。(如:&iArr[3])

? 数组名单独使用时,代表该数组的首地址。(iArr等同于&iArr[0])(注意:以后使用指针会经常用到这一点)

三、元素个数与赋值个数不一致时

当一个数组定义的长度大于赋值的长度时,超出的部分被放弃;当数组定义的长度小于赋值的长度时,不足的

部分被自动填上'\\0',对于数值类型的变量,实际上就是赋值为0,对于字符类型实际上就是赋值为NULL。

#include

int main(void) { int i;

int iNum[4] = {100, 150}; //后两个被填上0 char str1[10] = {'q', 'u', 'a', 'n', 'x', 'u', 'e'}; char str2[6] = \;

for (i=0; i<4; i++) { printf(\, iNum[i]); }

printf(\, str1); //7,8,9三个元素被填上NULL,所以可以用字符串输出

for (i=0; i<10; i++) { //故意循环到10, 看看后面是

否为“quanxue”

printf(\, str2[i]); //因为'e'和NULL被弃掉,所以不能用字符串输出 }

printf(\

return 0; }

本文来源:https://www.bwwdw.com/article/78fw.html

Top