定义但是未初始化,数组中有值,但是是垃圾值。 对于数组来说,一旦有元素被初始 化,其他元素都被赋值0。 计算数组中元素的个数
int count = sizeof(数组) / sizeof(数组[0]) // 数组的长度 = 数组占用的总字节数 / 数组元素占用的字节数在定义数组的时候[]里面只能写整型常量或者是返回整型常量的表达式,[]中不能放变量。
int length = 10; int Array[length ]; // 不报错, 但是没有初始化, 里面是随机值 int length = 10; int Array[length ] = {19, 22, 33} // 直接报错 int Array[5]; Array= {19, 22, 33}; // 错误。只能在定义数组的时候进行一次性(全部赋值)的初始化 #define length 10 int Array[length] = {0}; //正确当数组名作为函数参数时, 因为自动转换为了指针类型,所以在函数中无法动态计算除数组的元素个数。 在64位编译器下,指针类型默认为8个字节。 有的时候我们可能想要在一个函数里面动态计算数组的个数,所以可能会这么做:
void printMyArray(int myArray[]) { int length = sizeof(myArray) / sizeof(myArray[0]); for(int i = 0; i < length; i++) { printf("%i", myArray[i]); } } int main() { int myArray[5] = {1,2,3,4,5}; printMyArray(myArray); return 0; }可以看到在printMyArray函数中我们动态计算传进来的数组的个数,但是结果是错误的,因为它只能输出前两个数。 这是因为,在把数组当成函数的参数的时候,数组会被认为成指针,所以是8个字节,所以计算出的length是2,所以只能输出前两个数字。 解决:我们需要给出一个新的参数来获得length,在main()里面计算好length然后传入printMyArray。
void printMyArray(int myArray[], int length) { for(int i = 0; i < length; i++) { printf("%i ", myArray[i]); } } int main(int argc, const char * argv[]) { int myArray[5] = {1,2,3,4,5}; int length = sizeof(myArray) / sizeof(myArray[0]); printMyArray(myArray, length); return 0; }首先假设一个int类型一维数组arr[4], arr的地址是0x00; 那么arr +1是多少呢? arr是这个数组首元素地址==&arr[0], 无论&什么什么+1 就是&符号后面的内容占据的地址单元数+指针起始位置 arr[0]占据4地址单元 所以:
arr +1 == &arr[0]+1 =4+0x00=0x04; arr +2 == &arr[0]+2 =8+0x00=0x08;而 &arr+1 = 0x10; 这里&后面arr是个数组名就可以当成是arr这整个数组占据的地址单元数+地址.它占据16个地址单元 所以:
&arr+ 1=16+ 0x00= 0x10. &arr+ 2=32+ 0x00= 0x20.一维数组中各元素也是如此,arr[0]+1等于 arr[1]同样适用,arr[0]是int 类型在内存中占用四个字节,所以+1也是跳到第5个字节就是arr[1]的字节那儿,所以就是arr[1]了。
C语言中 int*p[4] 和 int(*p)[4]的区别
int *p[4]; //定义一个指针数组,该数组中每个元素是一个指针,每个指针指向哪里就需要程序中后续再定义了。 int (*p)[4]; //定义一个数组指针,该指针指向含4个元素的一维数组(数组中每个元素是int型)。区分int *p[n]; 和int (*p)[n]; 就要看运算符的优先级了。 int p[n]; 中,运算符[ ]优先级高,先与p结合成为一个数组,再由int说明这是一个整型指针数组。 int (*p)[n]; 中( )优先级高,首先说明p是一个指针,指向一个整型的一维数组。
int b[2]; int *a; a=b; //a指向数组b首地址,暨b[0]的地址 *a + 1 // *a就是取a指向地址的值,暨b[0],所以*a+1 == b[0]+1 *(a+1) // a+1,指针+1,就是指针指向下一个地址,暨b[1]的地址,所以*(a+1)== b[1]