一维数组
1.一维数组的定义格式为:
类型说明符 数组名[常量表达式]; 例如: int a[10];
它表示定义了一个整形数组,数组名为a,有10个元素。
2.在定义数组时,需要指定数组中元素的个数,方括弧中的常量表达式用来表示元素的个数,即数组长度。
3.常量表达式中可以包括常量和符号常量,但不能包含变量。
4.数组初始化
1)在定义数组时对数组元素赋以初值。
例如:int a[10]={0,1,2,3,4,5,6,7,8,9};
2)可以只给一部分元素赋值。例如:
int a[10]={0,1,2,3,4}; 定义a数组有10个元素,但花括弧内只提供5个初值,这表示只给前面5个元素赋初值,后5个元素值为0。
3)如果想使一个数组中全部元素值为0,可以写成:
int a[10]={0,0,0,0,0,0,0,0,0,0}; 或int a[10]={0};
4)在对全部数组元素赋初值时,由于数据的个数已经确定,因此可以不指定数组长度。
例如:int a[5]={1,2,3,4,5};也可以写成 int a[]={1,2,3,4,5};
5)a和&a的区别
定义一个数组,例如:int a[10]
a和&a两者都是地址且数值相等,但意义且不同。
a是数组名也是数组的首地址,&a是整个数组的地址。
示例:
#include
int main()
{
int a[5] = {0};
printf("a: %p\n", a);
printf("&a: %p\n", &a);
printf("a+1: %p\n", a + 1);
printf("&a+1: %p\n", &a + 1);
return 0;
}
二维数组
1.二维数组的定义格式为:
类型说明符 数组名[常量表达式][常量表达式];
例如:定义a为3×4(3行4列)的数组,b为5×10(5行10列)的数组。如下:float a[3][4],b[5][10] ;
2.数组初始化
4种方法对二维数组初始化:
1)分行给二维数组赋初值。
例如: int a[3][4]={{1,2,3,4},{5,6,7,8}, {9,10,11,12}};
2)以将所有数据写在一个花括号内,按数组排列的顺序对各元素赋初值。
例如:int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
3)可以对部分元素赋初值。
例如: int a[3][4]={{1}, {5}, {9}};也可以对各行中的某一元素赋初值,如int a[3][4]={{1}, {0,6}, {0, 0, 0, 11}};
4)如果对全部元素都赋初值,则定义数组时对第一维的长度可以不指定,但第二维的长度不能省。
例如:int a[3][4]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};等价于:、int a[ ][4]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
5)a、&a、a[0]、*a的区别
定义一个数组,例如int a[3][4] = {4, 5, 6};
a、&a、a[0]、*a四者在数值上相等,但意义不同。
a:第0行首地址,+1是加一行的字节数。
&a:整个数组地址,+1是加一个数组的字节数。
a[0]:第0行第0个元素的地址,+1是加一个元素的字节数。
*a:第0行第0个元素的地址,+1是加一个元素的字节数。
a[n] = *(a+0)
示例:
#include
int main()
{
int a[3][4] = {{4, 5}, {5}, {7,3}};
printf("a %p\n", a);
printf("&a %p\n", &a);
printf("a[0] %p\n", a[0]);
printf("*a %p\n", *a);
printf("\n");
printf("a+1 %p\n", a + 1);
printf("&a+1 %p\n", &a + 1);
printf("a[0]+1 %p\n", a[0] + 1);
printf("*a+1 %p\n", *a + 1);
return 0;
}
运行结果:a 0xbfb25b08
&a 0xbfb25b08
a[0] 0xbfb25b08
*a 0xbfb25b08
a+1 0xbfb25b18
&a+1 0xbfb25b38
a[0]+1 0xbfb25b0c
*a+1 0xbfb25b0c
6)思考:数组a[3][4],哪个不能表示a[1][1] (第四个)
*(a[1] + 1)
*(&a[1][1])
(*(a + 1))[1]
*(a + 5)
字符数组
1.字符数组的定义格式为:
char 数组名[常量表达式];
例如:char c[10];
2.初始化
对字符数组初始化,可逐个字符赋给数组中各元素。
例如:char c[10]={‘I’, ‘’,‘a’,‘m’,‘’,‘h’,‘a’,‘p’, ‘p’,‘y’}
3.字符数组的输入输出
字符数组的输入输出可以有两种方法:
逐个字符输入输出。用格式符“%c”输入或输出一个字符。
将整个字符串一次输入或输出。用“%s”格式符,意思是对字符串的输入输出。
说明:
(1)用“%s”格式符输出字符串时,printf函数中的输出项是字符数组名,而不是数组元素名。
(2)如果数组长度大于字符串实际长度,也只输出到遇′\0′结束。
(3)输出字符不包括结束符′\0′。
(4)如果一个字符数组中包含一个以上′\0′,则遇第一个′\0′时输出就结束。
(5)可以用scanf函数输入一个字符串。
4.字符数组常用函数
1)strcat函数
其一般形式为:strcat(字符数组1,字符数组2)
strcat的作用是连接两个字符数组中的字符串,把字符串2接到字符串1的后面,结果放在字符数组1中,函数调用后得到一个函数值——字符数组1的地址。
例如:
char str1[30]={″People′s Republic of ″};
char str2[]={″China″};
print(″%s″,strcat(str1,str2));
输出:
People′s Republic of China
2)strcpy函数
其一般形式为:strcpy(字符数组1,字符串2)
strcpy是“字符串复制函数”。作用:是将字符串2复制到字符数组1中去。
例如:
char str1[10],str2[]={″China″};
strcpy(str1,”china”);
(1)字符数组1必须定义得足够大,以便容纳被复制的字符串。字符数组1的长度不应小于字符串2的长度。
(2)“字符数组1”必须写成数组名形式(如str1),“字符串2”可以是字符数组名,也可以是一个字符串常量。如:strcpy(str1,″China″);
(3)复制时连同字符串后面的′\0′一起复制到字符数组1中。
(4)可以用strcpy函数将字符串2中前面若干个字符复制到字符数组1中去。
例如:strncpy(str1,str2,2);作用是将str2中前面2个字符复制到str1中去,然后再加一个‘\0’。
(5)不能用赋值语句将一个字符串常量或字符数组直接给一个字符数组。如:
str1=″China″; 不合法
str1=str2; 不合法
3)strcmp函数
其一般形式为:strcmp(字符串1,字符串2)
strcmp的作用是比较字符串1和字符串2。
例如:strcmp(str1,str2);
strcmp(″China″,″Korea″);
strcmp(str1,″Beijing″);
比较的结果由函数值带回
(1) 如果字符串1=字符串2,函数值为0。
(2) 如果字符串1>字符串2,函数值为一正整数。
(3) 如果字符串1<字符串2,函数值为一负整数。
4)strlen函数
其一般形式为:strlen (字符数组)
strlen是测试字符串长度的函数。函数的值为字符串中的实际长度(不包括′\0′在内)。
函数
1.函数形式
2.函数调用
函数调用过程:
1)函数名本身是一个地址,通过函数名找到函数的入口地址。
2)为形式参数分配内存空间。
3)传值(有值传递和地址传递)。注意形参与实参的个数、类型要一致。
4)执行函数体。
5)返回(有需要时返回)。
6)空间释放(释放栈空间)。
每一个进程被调用时都会被分配一个4G的虚拟空间,该虚拟空间又分为1G的内核态和3G的用户态。用户态由四部分构成:
数据段:存放全局变量、static修饰的变量。
代码段:存放代码、常量。
栈空间:存放局部变量、形参。
堆空间:
变量的存储类型
auto型:
局部变量默认为auto型实际上关键字“auto”可以省略,auto不写则隐含确定为“自动存储类别”,即动态存储方式。
register型:
运算是在寄存器中执行,而代码是在内存中执行,不能对寄存器变量取地址。
extern:
声明外部变量。如:extern int Abc; 注:声明不会分配内存。
static:
修饰全局变量时,改变其作用域,只能在本文件中使用;
修饰函数时,改变其作用域,只能在本文件中使用;
修饰局部变量时,改变其生命周期,直到程序运行结束才被释放。
预处理
1.预处理就是将#开头的文件、宏定义、条件编译等展开。
预处理是C语言的一个重要功能,它由预处理程序负责完成。
当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入对源程序的
译。 对源程序编译之前做一些处理,生成扩展C源程序。
2.种类:
宏定义 #define
文件包含 #include
条件编译 #if--#else--#endif等
格式:
#”开头
占单独书写行;语句尾不加分号;
在源程序中这些命令都放在函数之外,而且一般都放在源文件的前面,它们被称为预处部分
3.#include "stdio.h" 默认在当前目录中找该文件,一般用于用户自定义的头文件。
#include 默认在指定的文件目录中找该文件。
4.宏函数
不带参数的宏函数,如:
#define OUT printf(“Hello,World”);
即用OUT替换printf(“Hello,World”);即可。
带参数的宏,如:
#define S(a,b) a*b
area=S(3,2); 宏展开: area=3*2; 即形参用实参换,其它字符保留
思考题:
#define SQR(X) X*X
int k = 2, m = 1;
SQR(k + m);
展开为: 2 + 1 * 2 + 1 结果为5