1、数组是存储多个相同类型数据的集合,数组的大小取决于数组的元素个数和元素类型。
2、指针存放其所指向的变量的地址。在32位平台下,指针的大小是4个字节;在64位平台下,指针的大小是8个字节。
3、绝大多数情况下,数组名表示数组首元素的地址。
两种例外:sizeof(数组名)——计算整个数组的大小;&数组名——取出的是整个数组的地址。
从地址值的角度来看,&数组名和首元素地址是一样的,但意义不同。&数组名的类型是数组指针,数组名和&数组名[i]的类型是指针。
4、sizeof()其实是一个运算符,主要用来计算所占空间字节的大小。sizeof()是在编译阶段计算结果,括号里面的表达式不会进行,看最后表达式的类型决定大小。其返回值默认是无符号的整数类型。
5、strlen()是库函数,计算字符串长度,从传入地址开始计数,直到遇到’\0’计数停止。strlen()在运行阶段才能计算,返回值类型是无符号的整数类型。
int main()
{
//一维数组
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a)); //16,计算整个数组大小
printf("%d\n", sizeof(a + 0)); //4/8,数组首元素的地址
printf("%d\n", sizeof(*a)); //4,计算数组首元素大小
printf("%d\n", sizeof(a + 1)); //4/8,数组第二个元素的地址
printf("%d\n", sizeof(a[1])); //4,计算数组第二个元素大小
printf("%d\n", sizeof(&a)); //4/8,整个数组的地址
printf("%d\n", sizeof(*&a)); //16,相当于sizeof(a)
printf("%d\n", sizeof(&a + 1)); //4/8,跳过一个数组
printf("%d\n", sizeof(&a[0])); //4/8,数组首元素的地址
printf("%d\n", sizeof(&a[0] + 1)); //4/8,数组第二个元素的地址
//字符数组
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr)); //6,计算整个数组大小
printf("%d\n", sizeof(arr + 0)); //4/8,数组首元素地址
printf("%d\n", sizeof(*arr)); //1,计算数组首元素大小
printf("%d\n", sizeof(arr[1])); //1,计算数组第二个元素大小
printf("%d\n", sizeof(&arr)); //4/8,整个数组地址
printf("%d\n", sizeof(&arr + 1)); //4/8,跳过一个数组
printf("%d\n", sizeof(&arr[0] + 1)); //4/8,数组第二个元素的地址
printf("%d\n", strlen(arr)); //随机值
printf("%d\n", strlen(arr + 0)); //随机值
printf("%d\n", strlen(*arr)); //err,输入不是字符串起始地址
printf("%d\n", strlen(arr[1])); //err
printf("%d\n", strlen(&arr)); //随机值
printf("%d\n", strlen(&arr + 1)); //随机值,跳过一个数组
printf("%d\n", strlen(&arr[0] + 1)); //随机值,从第二个元素往后
char arr[] = "abcdef";
//在内存中存放的是:a b c d e f \0
printf("%d\n", sizeof(arr)); //7,计算整个数组大小
printf("%d\n", sizeof(arr + 0)); //4/8,数组首元素地址
printf("%d\n", sizeof(*arr)); //1,计算数组首元素大小
printf("%d\n", sizeof(arr[1])); //1,计算数组第二个元素大小
printf("%d\n", sizeof(&arr)); //4/8,整个数组地址
printf("%d\n", sizeof(&arr + 1)); //4/8,跳过整个数组
printf("%d\n", sizeof(&arr[0] + 1)); //4/8,数组第二个元素地址
printf("%d\n", strlen(arr)); //6,计算字符串长度,不包括\0
printf("%d\n", strlen(arr + 0)); //6
printf("%d\n", strlen(*arr)); //err
printf("%d\n", strlen(arr[1])); //err
printf("%d\n", strlen(&arr)); //6,计算字符串长度
printf("%d\n", strlen(&arr + 1)); //随机值,跳过整个数组
printf("%d\n", strlen(&arr[0] + 1)); //5,从第二个字符往后的长度
char* p = "abcdef";
//指针p存放的是a的地址
printf("%d\n", sizeof(p)); //4/8
printf("%d\n", sizeof(p + 1)); //4/8,b的地址
printf("%d\n", sizeof(*p)); //1,计算a的大小
printf("%d\n", sizeof(p[0])); //1,计算a的大小
printf("%d\n", sizeof(&p)); //4/8,p的地址
printf("%d\n", sizeof(&p + 1)); //4/8,p相邻下一个地址
printf("%d\n", sizeof(&p[0] + 1)); //4/8,b的地址
printf("%d\n", strlen(p)); //6,计算字符串长度
printf("%d\n", strlen(p + 1)); //5,计算从第二个字符往后的字符串长度
printf("%d\n", strlen(*p)); //err
printf("%d\n", strlen(p[0])); //err
printf("%d\n", strlen(&p)); //随机值,p的地址,不知道\0
printf("%d\n", strlen(&p + 1)); //随机值
printf("%d\n", strlen(&p[0] + 1)); //5,计算从第二个字符往后的字符串长度
//二维数组
int a[3][4] = { 0 };
//二维数组的首元素是第一行
printf("%d\n", sizeof(a)); //48,计算整个数组大小
printf("%d\n", sizeof(a[0][0])); //4,计算数组首元素大小
printf("%d\n", sizeof(a[0])); //16,计算第一行的大小
printf("%d\n", sizeof(a[0] + 1)); //4/8,第一行第二个元素的地址,a[0]+1相当于&a[0][1]
printf("%d\n", sizeof(*(a[0] + 1))); //4,计算a[0][1]的大小
printf("%d\n", sizeof(a + 1)); //4/8,第二行的地址
printf("%d\n", sizeof(*(a + 1))); //16,计算第二行大小
printf("%d\n", sizeof(&a[0] + 1)); //4/8,第二行的地址
printf("%d\n", sizeof(*(&a[0] + 1))); //16,计算第二行的大小
printf("%d\n", sizeof(*a)); //16,计算第一行的大小
printf("%d\n", sizeof(a[3])); //16,由于表达式不会被执行,所以不会越界
return 0;
}
指针习题
int main()
{
int a[4] = { 1, 2, 3, 4 };
int* ptr1 = (int*)(&a + 1); //跳过整个数组
int* ptr2 = (int*)((int)a + 1);
//a表示数组名首地址,地址值强制转换为整型,加1后又强制转换为整形指针,相当于指针跳过一个字节
//在内存中小端存储
//低地址--->高地址 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
// /|\
// |ptr2
//此时ptr2中的内容为0x02000000
printf("%x,%x", ptr1[-1], *ptr2); //ptr1[-1] ---> *(ptr1-1)
//int a[3][2] = { {0, 1}, {2, 3}, {4, 5} }; //数组内容为0 1 2 3 4 5
int a[3][2] = { (0, 1), (2, 3), (4, 5) }; //数组元素是逗号表达式,数组内容为1 3 5 0 0 0
int* p;
p = a[0]; //二维数组第一行的数组名,表示第一行的首元素
printf("%d", p[0]); //p[0] ---> *(p+0)
return 0;
}
int main()
{
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptr1 = (int*)(&aa + 1); //跳过整个数组
int* ptr2 = (int*)(*(aa + 1)); //aa表示二维数组第一行,加1跳过一行
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1)); //*(ptr1 - 1) ---> ptr1[-1]
return 0;
}
int main()
{
char* c[] = { "ENTER","NEW","POINT","FIRST" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *-- * ++cpp + 3);
printf("%s\n", *cpp[-2] + 3);
printf("%s\n", cpp[-1][-1] + 1);
return 0;
}
int main()
{
int a[5][5];
int(*p)[4]; //数组指针,指向四个元素的数组
p = a; //a表示二维数组首元素地址
printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
//两个指针相减得到两指针之间元素个数,%p打印地址,-4的十六进制
return 0;
}
版权声明:本文为minLi_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。