数组和指针

  • Post author:
  • Post category:其他


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 版权协议,转载请附上原文出处链接和本声明。