//int main()
//{
// // 指针 是唯一标识内存的唯一标识
// int a = 0; // 创建 a空间,a变量有属于自己的唯一地址空间 ,而这个变量的空间内存放的是 被初始化的 0.
// // a的地址又被称为 左值,左值代表的是地址值,不可随便更改,所造成的后果的是 无法正常通过地址 找到所在的地址的空间
// // a的空间又被称为 右值,右值代表的是地址空间所存放的东西,是可以任意修改的(但是需要注意的是 注意类型是否相同)
//
// int* pa = &a;// int* 类型的指针变量 pa拥有自己的地址 ,而空间就是用来存放 a的地址,
// // &pa 就是 左值
// // pa 就是 右值
//
// *pa = 10;// * :称为解引用,而 *pa 就是通过pa 里所存放的是地址 找到所存放的地址空间 然后将值改变(传参时不传地址 所指向的地址空间就不是同一块,需要传地址,才能指向同一块空间)
//
// printf("%d\n", a);// 10 因为通过 地址找到a的空间,然后改变了值 所以变为 0;
// printf("%d\n", *pa);// 10
//
// // 重要!!
// // 指针大小 记住只要是指针 32位下就是 4字节,64位下就是 8字节,!!!!!!!!!!!!!!!!!!!!!!!!!!!
// // 注意的是 当输出时地址看一看时 所看见的是以 16进制展示出来的,并且是起始地址 的第一个字节‘
// // 而我们日常所写的指针类型 所包含的意思是 规定指针在访问时的步长,也就是字节数cahr* 在解引用时只允许访问一个字节数,int* 在解引用时只允许访问4个字节数
//
// return 0;
//}
// 计算机是如何进行运算的
//! 计算机底层是被规定为 最小运算字节是int类型的,就是 最小为4字节运算
//! 所以 如果是4字节以下的字节数 在进行运算时 会发生 整型提升 也就是说 会在运算时先提升为int类型再进行相关运算 (char也属于int家族,实际存储的是 ASCII码值)
//! 但是 在进行补码的运算完成后 存储不下,就会发生 截断,补码,不会考虑任何因素 能存放多少 就截断多少二进制位数,然后存放到原变量类型时就会 进行一样的解读,补码看符号位之类的运算
//!
//! 如果是大于int类型但是 类型并不相同时 就会发生隐式转换 将类型提升至较大的一方 然后在进行相关运算,同理 小的哪一方在运算结束后会发生 截断
//!
// scanf 不能用于输入 有空格 字符串
// gets() 可以
// 指针类型的作用
//int main()
//{
// int a = 0x11223344; // 16进制 4个二进制位对应一个16进制数,小端 可以看到内存中是倒着存放的
// int* pa = &a;
// char* pc = (char*)&a;
//
// printf("%x\n", *pa);// 11223344 %d 以10进制有符号形式打印, %x 以16进制有符号形式打印
// printf("%x\n", *pc);// 44 (小端) 大端 11
//
// // 打印地址 %p
// printf("%p\n", pa);// 地址相同 指向的都是指针的起始位置地址
// printf("%p\n", pc);// 地址 在计算机中 访问内存时 是由地址向高地址依次访问的(单位:字节)
//
// printf("%p\n", pa+1);// 地址值 一次加 4
// printf("%p\n", pc+1);// 地址值 一次加 1 (单位:字节
//
// //*pa = 0;
// //printf("%x\n", *pa);// 0 一次性访问4个字节 并将值改为 0
//
// //*pc = 0;
// //printf("%x\n", *pa);// 11223300 一次访问一个字节 并将一个字节值改为 0
//
//
// return 0;
//}
// void* --> ((void*)0) 将0 强转为一个指针
//int b = 2;
//void test(void* p)
//{
// printf("%d\n", *(int*)p);
// p = &b;// 指针变量也是变量 需要传值才可以改变原值
//}
//void test1(void** p)
//{
// void* p1 = *p;// 传二级指针 最好先用一个一级指针来代为接收,方便操作
// printf("%d\n", *(int*)p1);
// /**(int*)p1 = 1;*/
// *p = &b;
//}
//void test2(int x)
//{
// x = 1;
//}
//int main()
//{
// int a = 10;
// int* pa = &a;
// void* pv = &a;
// // void* 被称为 泛型指针 可以接收任何类型的指针,但是不可以直接解引用需要进行强转为想要的类型才可以
// //int b = 2;
//
// test(pa);// 传值
// //test1(&pa);// 传地址
//
// //test2(a);
// printf("hh\n");
// printf("%d\n", *pa);
//
// return 0;
//}
const 修饰指针
//int main()
//{
// int a = 10;
// const int* pa = &a; // 放在* 左边修饰的是 指针所指向的内容不可更改 但是地址可以更改
// // 放在* 右边修饰的是 指针所指向的地址不可更改,但是内容可以更改
// // const是 让变量拥有常属性的关键字 但是其变量本质依旧是变量 并不是真正的常量,只是不让使用者进行修改操作
// // define 定义的宏是 常量 不是变量 (所完成的是替换工作,在预处理期间就会完成替换工作,,所要注意的是 表达式子在完成宏替换后的优先级问题,千万注意,最好+括号括起来)
//
//
// return 0;
//}
// 指针运算
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
int sz = sizeof(arr) / sizeof(int);
int* p = arr;// arr 等同于 arr[0]
int i = 0;
//for (; i < sz; i++)
//{
// *(p + i) = 0;// 利用指针进行赋值为全0
// // 等同于 arr[i]=0;
// // 指针 会根据指针的类型 依次向后i个字节数进行移动
//}
// 指针—指针的作用
// 根据指针的类型大小 相减可以得到之间的元素个数
printf("%d\n", p-(p+sz));// -10 注意的就是 得到的值加个绝对值就OK了
// 指针 - 指针 注意的点是 必须指向的是同一块空间,而不是 不同的空间,!!!
return 0;
}
待续~~