1、地址
a、计算机中的内存是以字节为单位的存储空间。
b、内存的每一个字节都有一个唯一的编号,这个编号就成为地址。
c、凡存放在内存中的程序和数据都有一个地址,也就是说,一个函数也有自己的内存地址。
d、酒店中以房间为单位,每个房间有一个房号。
e、当定义一个变量时,系统就分配一个带有唯一地址的存储单元来存储这个变量。比如:
char a = 'A';
int b = 66;
在16bit编译器环境下,系统为a、b分别分配1个字节、2个字节的存储单元。变量存储单元的第一个字节的地址就是该变量的地址。
可以看出,变量a的地址是ffc3;变量b的地址是ffc1。内存中存储的都是2进制数据。
f、打印查看地址(用 & 符号)
int c = 10;
// 以16进制形式输出地址
printf("16进制:%x\n", &c);
// 以10进制形式输出地址
printf("10进制:%d", &c);
2、一维数组
a、为什么要用数组?举个例子:
// 定义一个人的年龄
int age;
// 定义五个人的年龄
int age1, age2, age3, age4, age5;
// 那定义五十个,五百个,五千个人的年龄呢???
// 数组是可以用来存储相同类型的不同变量
int ages[50];
b、一些错误的写法
int a[]; // 没有指定元素个数
int[5] a; // 中括号不能放变量名前面
int i = 9;
int a[i]; // 不能用变量做元素个数
c、数组的地址
int ages[5]; // 64位环境下占用 4*5=20 个字节
// 1.计算数组占据的存储空间
size_t size = sizeof(ages);
printf("ages占据的字节:%d", size); // 20
// 2.查看数组的地址
printf("%d", &ages[0]); // 第0个元素的地址就是数组的地址
printf("%d", ages); // 数组名也代表整个数组的地址,也就是数组的起始地址
// 3.ages是常量,不能赋值,代表数组的地址
d、数组的初始化
// 1
int a[2] = {8, 10};
// 2
int b[2];
b[0] = 8;
b[1] = 10;
// 3
int c[4] = {8, 10}; // 当数组为整型时,初始化未确定的元素默认为0,c[2]=c[3]=0
// 4
int d[] = {8, 9, 10}; // 当数组全部赋值时,可省略元素个数
e、传递数组参数
void test1(int a) {
a = 9;
}
void test2(int b[]) { // 形参数组的元素个数可以省略
b[0] = 10;
}
int main() {
int c[3] = {1, 2, 3};
printf("未调用函数前c[0]的值:%d\n", c[0]);
// 一维数组的元素当做参数的话,跟普通类型的变量当做参数一样,是单向的参数传递
// 形参的改变不影响实参
test1(c[0]);
printf("调用test1函数后c[0]的值:%d\n", c[0]);
// 数组名代表数组地址,数组名当做参数,传递的是整个数组,主要是传递数组的地址
// 形参修改时会影响实参
test2(c);
printf("调用test2函数后c[0]的值:%d\n", c[0]);
return 0;
}
结果是:
2、二维数组
a、定义
int a[2][3]; // 共2行3列,2*3=6个元素
b、存储:
1、C语言把二维数组当做是一维数组的集合,即二维数组是一个特殊的一维数组:它的原始是一维数组。
2、例如 int a[2][3] 可以看做由一维数组 a[0] 和一维数组 a[1] 组成,这两个一维数组都包含了3个int类型的元素
3、二维数组的存放顺序是按行存放的,先存放第一行的元素,再存放第2行的元素。
4、例如 int a[2][3] 存放顺序是:a[0][0] → a[0][1] → a[0][2] → a[1][0] → a[1][1] → a[1][2]
5、内存中的存储情况,例如 int a[2][2]
// 二维数组地址
int a[2][3];
// a 代表整个数组的地址,也是 a[0] 数组的地址,也是变量 a[0][0] 的地址
printf("%d", a);
printf("%d", a[0]); // a[0]也是数组名,所以不需加 & 符号
printf("%d", &a[0][0]);
// a[1]数组的地址,也是变量 a[1][0]的地址
printf("%d", a[1]);
printf("%d", &a[1][0]);
c、初始化
// 1、按行进行初始化
int a[2][3] = { {1, 2, 3}, {4, 5, 6} };
// 2、按存储顺序进行初始化(先放第一行,再放第二行)
int a[2][3] = {1, 2, 3, 4, 5, 6};
// 3、可省略行数,但不能省略列数
int a[][3] = {1, 2, 3, 4, 5, 6};