数组和指针
标量变量 :只存储单个值的变量。
与普通变量类似,在使用数组元素之前,一定一定要先给他们赋初值。
注意 存储类别警告 :对于一些其他存储类别的变量和数组,如果在声明时未初始化,编译器会自动把它们的值设置为0。#存储类别
目前描述的变量属于自动存储类别
- 初始化数组:
- 如果不初始化数组,数组元素和未初始化的普通变量一样,其中存储的都是垃圾值;
- 如果部分初始化数组,剩余的元素就会被初始化为0;
- 如果初始化列表的项数多余数组元素个数,编译器则会报错;
- 最好是在声明数组时使用符号常量来表示数组的大小,这样做就能够确保整个程序中的数组大小始终一致。
- 指定初始化器(C99):
int arr[10] = { [5] = 211,985 };
//把arr[5]初始化为211,arr[6]初始化为985,其他元素将会被赋值为0。
关于指定初始化器的两个特性:
1. 如果指定初始化器后面有更多的值,那么后面这些值将会被用于初始化指定元素后面的元素;
2. 如果再次初始化指定的元素,那么最后的初始化将会取代之前的初始化。
- 给数组元素赋值:
- C不允许把数组作为一个单元赋给另一个数组;
- 除初始化外,不允许使用花括号列表的形式赋值。
- 多维数组:
- 在计算机内部,二维数组是先存储第一行的元素,然后顺序存储第二行的元素,以此类推;
- 初始化二维数组,对于arr[5][12],按照5个列表来进行初始化,如果第1个列表只有10个数,则只会初始化数组第1行的前10个元素,而最后两个元素会被初始化为0。如果某列表中的数值个数超出了数组每行的元素个数,则会出错,但是不影响其他行的初始化。
- 指针和数组:
- 数组名是数组首元素的地址;
- 在C中,指针加1指的是增加一个存储单元(所指向类型的大小。eg. short为2字节,double为8字节)
a == &a[0]; //a是一个数组,该表达式值为1
a + 2 == &a[2]; //相同的地址
*(a + 2) == a[2]; //相同的值
- 函数、数组和指针:
- 定义的函数的形式参数是一个数组,那么在函数原型声明和函数定义头里可以用指针来代替这个数组,在这种情况下,数组和指针是可以通用的;
- 数组名时该数组首元素的地址,作为实际参数的数组名要求形式参数是一个与之匹配的指针。在这种情况下,C会把int arr[]和int *arr解释成一样;
- 在函数原型中,可以省略参数名;
- 但是在函数定义中不能省略参数名。
int sum ( int *arr , int n );
int sum ( int * , int );
int sum ( int arr[] , int n ); //调用函数时直接使用数组的名称
int sum ( int [] , int ); //这四种原型是等价的
int sum ( int *arr , int n )
{
//其他代码已省略
}
int sum ( int arr[] , int n )
{
//其他代码已省略
}
- 指针表示法和数组表示法:
- 处理数组的函数实际上用指针作为参数;
- 在C语言中,arr[i]和*(arr+i)是等价的。无论arr是数组名还是指针变量,这两个表达式都是可用的。但是,只有当arr是指针变量时,才能使用arr++这种表达式。
- const和指针:
- const int *p = 非const数据地址; ✔️
const int *p = const数据地址; ✔️ 不能通过这种指针改变数据
普通指针 = const数据地址。 ✖️ - int * const p 该指针在声明并初始化一个指向的地址,定义后不可修改
- const int * const p 该指针既不能修改指向地址的值,也不能更改它的指向
- const int *p = 非const数据地址; ✔️
欢迎收藏我的个人博客地址
个人博客地址