#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
//第一个参数:待排序数组的首元素地址
//第二个参数:待排序数组的元素个数
//第三个参数:待排序数组的每个元素的大小 - 单位是字节
//第四个参数:是函数指针,比较两个元素所用函数的地址 - 这个函数使用者自己实现
// 函数指针的两个参数是:待比较的两个元素的地址
//struct Stu
//{
// char name[20];
// int age;
//};
//
//void Swap(char* buf1, char* buf2,int width)
//{
// int i = 0;
// for (i = 0; i < width; i++)
// {
// char tmp = *buf1;
// *buf1 = *buf2;
// *buf2 = tmp;
// buf1++;
// buf2++;
// }
//}
//实现bubble_sort函数的程序员,他是否知道未来排序的数据类型 - 不知道
//那程序员也不知道待比较的两个元素的类型
//void bubble_sort(void* base, int sz, int width,int(*cmp)(void* e1,void* e2))
//{
// int i = 0;
// //趟数
// for (i = 0; i < sz - 1; i++)
// {
// //每一趟比较的对数
// int j = 0;
// for (j = 0; j < sz - 1 - i; j++)
// {
// //两个元素的比较
// if (cmp((char*)base+j*width,(char*)base+(j+1)*width) > 0)
// {
// //交换
// Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
// }
// }
// }
//}
//int cmp_int(const void* e1,const void* e2)
//{
// //比较两个整型值
// return *(int*)e1 - *(int*)e2;
//}
//int cmp_stu_by_age(const void* e1, const void* e2)
//{
// return((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
//}
//int cmp_stu_by_name(const void* e1, const void* e2)
//{
// return strcmp(((struct Stu*)e1)->name,((struct Stu*)e2)->name);
//}
//void test4()
//{
// int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
// int sz = sizeof(arr) / sizeof(arr[0]);
// //使用bubble_sort的程序员一定知道自己排序的是什么类型的数据
// //就应该知道如何比较待排序数组中的元素
// bubble_sort(arr,sz,sizeof(arr[0]),cmp_int);
//}
//void test5()
//{
// struct Stu s[3] = { {"zhangsan",20},{"lisi",30},{"wangwu",10}};
// int sz = sizeof(s) / sizeof(s[0]);
// bubble_sort(s, sz, sizeof(s[0]), cmp_stu_by_name);
//}
//
//int main()
//{
// //test4();
// test5();
//}
//一维数组
//int main()
//{
// //数组名是首元素地址
// //1.sizeof(数组名) - 数组名表示整个数组
// //2.&数组名 - 数组名表示整个数组
// int a[] = { 1,2,3,4 };
// printf("%d\n", sizeof(a));//16 sizeof(数组名) - 计算的是数组总大小 - 单位是字节 - 16
// printf("%d\n", sizeof(a + 0));//4/8 - 数组名这里表示首元素地址 - a + 0 还是首元素地址,地址的大小就是4/8个字节
// printf("%d\n", sizeof(*a));//4 - 数组名表示首元素地址,*a就是首元素,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 &a取出的是数组的地址,但是数组的地址也是地址,地址的大小就是4/8个字节
// printf("%d\n", sizeof(*&a));//16
// printf("%d\n", sizeof(&a+1));//4/8 &a是数组的地址,&a+1虽然地址跳过整个数组,但还是地址,所以是4/8个字节
// printf("%d\n", sizeof(&a[0]));//4/8 第一个元素的地址
// printf("%d\n", sizeof(&a[0]+1));//4/8 第二个元素的地址
//
// return 0;
//}
//字符数组
//int main()
//{
// char arr[] = { 'a','b','c','d','e','f' };
// printf("%d\n", sizeof(arr));//6 sizeof计算的是数组大小,6*1 = 6字节
// printf("%d\n", sizeof(arr + 0));//4/8 arr是首元素的地址,arr+0还是首元素的地址,地址的大小是4/8字节
// printf("%d\n", sizeof(*arr));//1 arr是首元素地址,*arr就是首元素,首元素是字符,大小是一个字节
// printf("%d\n", sizeof(arr[1]));//1
// printf("%d\n", sizeof(&arr));//4/8
// printf("%d\n", sizeof(&arr + 1));//4/8 &arr+1是跳过整个数组后的地址,地址大小是4/8个字节
// printf("%d\n", sizeof(&arr[0] + 1));//4/8 第二个元素的地址
// return 0;
//}
//int main()
//{
// char arr[] = { 'a','b','c','d','e','f' };
// 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));//随机值-6
// printf("%d\n", strlen(&arr[0]+1));//随机值-1
//
// return 0;
//}
//int main()
//{
// char arr[] = "abcdef";
// printf("%d\n", sizeof(arr));//7 - a b c d e f \0
// printf("%d\n", sizeof(arr+0));//4/8 计算的是地址的大小 - arr+0是首元素的地址
// printf("%d\n", sizeof(*arr));//1 *arr是首元素,sizeof(*arr)计算首元素的大小
// printf("%d\n", sizeof(arr[1]));//1 第二个元素的大小
// printf("%d\n", sizeof(&arr));//4/8 &arr虽然是地址的地址,但也是地址,所以是4/8个字节
// printf("%d\n", sizeof(&arr+1));//4/8
// printf("%d\n", sizeof(&arr[0]+1));//4/8
// return 0;
//}
//int main()
//{
// char arr[] = "abcdef";
// printf("%d\n", strlen(arr));//6
// 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 &arr - 数组的地址 - 数组指针char(*p)[7] = &arr
// printf("%d\n", strlen(&arr+1));//随机值
// printf("%d\n", strlen(&arr[0]+1));//5
//
// return 0;
//}
//int main()
//{
// char* p = "abcdef";//p里存的是数组的首元素地址
//
// printf("&d\n", sizeof(p));//4/8 计算指针变量p的大小
// printf("&d\n", sizeof(p+1));//4/8 p+1得到的是字符b的地址
// printf("&d\n", sizeof(*p));//1 *p 就是字符串的第一个字符 - ‘a’
// printf("&d\n", sizeof(p[0]));//1
// printf("&d\n", sizeof(&p));//4/8
// printf("&d\n", sizeof(&p+1));//4/8
// printf("&d\n", sizeof(&p[0]+1));//4/8
//
// return 0;
//}
//int main()
//{
// char* p = "abcdef";
//
// 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));//随机值
// printf("%d\n", strlen(&p+1));//随机值
// printf("%d\n", strlen(&p[0]+1));//5
//
// return 0;
//}
//二维数组
int main()
{
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a[0][0]));
printf("%d\n", sizeof(a[0]));
printf("%d\n", sizeof(a[0]+1));
printf("%d\n", sizeof(*(a[0]+1)));
printf("%d\n", sizeof(a+1));
printf("%d\n", sizeof(*(a+1)));
printf("%d\n", sizeof(&a[0]+1));
printf("%d\n", sizeof(*( &a[0] + 1)));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a[3]));
return 0;
}