指针是内存中一个最小单元的编号,也就是地址
平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
总结:指针就是地址,口语中说的指针通常指的是指针变量


- // 指针是什么?
- // 1.指针是内存中一个最小单元的编号,也就是地址
- // 2.平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
- // 总结:指针就是地址,口语中说的指针通常指的是指针变量
- int main()
- {
- int a = 100; //在内存中开辟一块空间
- int * pa = &a; //pa是专门来存放地址(指针)的,pa在这里就被称为指针变量
- //这里我们对变量a,取出它的地址,可以使用&操作符
- //a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量中,p就是一个指针变量
- // int arr[10];
- // printf("%p\n",&a);
- printf("%p\n",pa);
-
-
- return 0;
-
- }

int* 的指针解引用访问4个字节
char* 的指针解引用访问1个字节
结论:指针类型可以决定指针解引用的时候访问多少个字节(指针的权限)
int* 4个字节 char* 1个字节 short* 2个字节 float* 4个字节 double* 8个字节
- //指针类型的意义
- int main()
- {
- int a = 0x11223344; //0x开头是16进制数字
-
- //int * pa = &a;
- char * pa = &a;
- // int* 的指针解引用访问4个字节
- // char* 的指针解引用访问1个字节
- // 结论:指针类型可以决定指针解引用的时候访问多少个字节(指针的权限)
- *pa = 0;
-
- return 0;
- }
- //type * p *说明p是指针变量
- //1. p指向的对象的类型
- //2. p解引用的时候访问的对象大小是sizeof(type)
-
- int main()
- {
- int a = 0x11223344; //0x开头是16进制数字
-
- int* pa = &a;
- char* pc = &a;
- printf("%p\n",pa); //0x16d207388
- printf("%p\n",pc);//0x16d207388
-
- //int * 增加4个字节,char * 增加1个字节
- printf("%p\n",pa+1); //0x16d20738c
- printf("%p\n",pc+1);//0x16d207389
- //指针类型决定指针+1/-1操作时的步长
- //整形指针+1跳过4个字节
- //字符指针+1跳过1个字节
-
- return 0;
- }
- //野指针
- // int main()
- // {
- // int a = 10;
- // int* pa = &a;
- // *pa = 20;
- // printf("%d\n",a);
-
- // return 0;
- // }
-
-
- //p是野指针 野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
- // int main()
- // {
- // int* p; //局部变量不初始化的时候,内容是随机值
- // *p = 20;
- // printf("%d\n",*p);
-
- // return 0;
- // }
-
- //指针越界访问
- // int main()
- // {
- // int arr[10] = {0};
- // int* p = arr;
- // int i = 0;
- // for(i = 0; i<= 11;i++)
- // {
- // //当指针指向的范围超出数组arr的范围时,p就是野指针
- // *(p++) = i;
- // }
- // return 0;
- // }
-
- //指针释放
- int* test()
- {
- int a = 110;
- return &a;
- }
- int main()
- {
- int* p = test();
- printf("%d\n",*p);
-
-
- return 0;
- }
1指针初始化
2小心指针越界
3指针指向的空间释放,及时置NULL
4避免返回局部变量的地址
5指针使用之前检查有效性
- // 如何规避野指针:
- // 1指针初始化
- int main()
- {
- int a = 0;
- int* p = &a;
-
- int* ptr = NULL; //告诉你ptr是一个空指针,没有指向任何有效的空间,这个指针不能直接使用
- int* ptr2; //野指针
-
- if (ptr != NULL)
- {
- //使用
- }
-
-
- return 0;
- }
- // 2小心指针越界
- // 3指针指向的空间释放,及时置NULL
- // 4避免返回局部变量的地址
- // 5指针使用之前检查有效性

指针+ - 整数
- //指针运算
- // int main()
- // {
- // int arr[10] = {0};
- // //不使用下标访问数组
- // int* p = &arr[0];
- // int i = 0;
- // int sz = sizeof(arr)/sizeof(arr[0]);
- // for (int i = 0; i < sz; i++)
- // {
- // *p = i;
- // p++; // p = p+1
- // }
- // p = arr;
-
- // for (i = 0; i < sz; i++)
- // {
- // printf("%d ",*(p+i)); // p+i
- // }
-
- // // for (i = 0; i < 10; i++)
- // // {
- // // printf("%d",arr[i]);
- // // }
-
- // return 0;
- // }
-
- //int arr[10];
- //int* p = arr;
- //*(p+i) == arr[i]
- //*(arr+i) == arr[i]
- //数组名是首元素的地址 -- 指针
- //arr[i] == *(arr+i) == *(i+arr) == i[arr]
-
- int main()
- {
- int arr[10] = {1,2,3,4,5,6,7,8,9,10};
- int i = 0;
- int *p = arr;
- for(i = 0;i < 10; i++)
- {
- printf("%d ",i[arr]); //[]操作符
- printf("%d ",*(p+i)); //[]操作符
- }
-
- //arr[i] --> i[arr]
-
-
- return 0;
-
- }
-
- // int my_strlen(char* s)
- // {
- // int count = 0;
- // while (*s != '\0')
- // {
- // count++;
- // s++;
- // }
-
- // return count;
- // }
-
- //递归实现
- // int my_strlen(char* s)
- // {
- // if (*s == '\0')
- // {
- // return 0;
- // } else
- // {
- // return 1 + my_strlen(s + 1);
- // }
- // return 0;
- // }
- int my_strlen(char* s)
- {
- char* start = s;
- while (*s != '\0') //(*s)
- {
- s++;
- }
- // while (*s++); //err
- //while (*s++); return s -start-1; //true
-
- return s -start;
-
- }
-
- int main()
- {
- char arr[] = "abcdef"; // a b c d e f \0
- int len = my_strlen(arr);
- printf("%d\n",len);
-
- return 0;
- }
- //指针和数组之间是什么关系呢?
- //指针变量就是指针变量,不是数组,指针变量的大小是4/8个字节,专门是用来存放地址的
- //数组就是数组,不是指针,数组一块连续的空间,可以存放一个或者多个类型相同的数据
- //指针和数组之间的关系:数组中,数组名其实是数组首元素的地址,数组名 == 地址 == 指针
- //当我们知道数组首元素的地址的时候,因为数组又是连续存放的,使用通过指针就可以遍历访问数组,数组是可以通过指针访问的
- // int main()
- // {
- // int arr[10] = {1,2,3,4,5,6,7,8,9,10};
- // int i = 0;
- // int sz = sizeof(arr) / sizeof(arr[0]);
- // int* p = arr;
- // for(i = 0; i < sz; i++)
- // {
- // printf("%p == %p\n",p+i,&arr[i]);
- // }
-
- // return 0;
- // }
-
- // int main()
- // {
- // int a = 10;
- // int* p = &a;//p是一级指针变量,指针变量也是变量,变量是在内存中开辟空间的
- // int** pp = &p; //pp就是二级指针,二级指针变量就是用来存放一级指针变量的地址
- // *(*pp) = 100;
- // *p = 10;
- // int** * ppp = &pp;
- // //int* 是在说明pp指向的是int*类型的变量
- // printf("%d\n",a);
- // printf("%p\n",&a);
- // printf("%p\n",&p);
- // printf("%p\n",pp);
-
- // return 0;
- // }
- // int main()
- // {
- // int a = 10;
- // int* p = &a;//p是一级指针变量,指针变量也是变量,变量是在内存中开辟空间的
- // int** pp = &p; //pp就是二级指针,二级指针变量就是用来存放一级指针变量的地址
- // *(*pp) = 100;
- // *p = 10;
- // int** * ppp = &pp;
- // //int* 是在说明pp指向的是int*类型的变量
- // printf("%d\n",a);
- // printf("%p\n",&a);
- // printf("%p\n",&p);
- // printf("%p\n",pp);
-
- // return 0;
- // }
-
- int main()
- {
- char arr1[] = "abcdef";
- char arr2[] = "hello world";
- char arr3[] = "xiaofan";
-
- char* parr[] = {arr1,arr2,arr3};
- int i = 0;
- int sz = sizeof(parr)/sizeof(parr[0]);
-
-
- char** p = parr;
- for (i = 0;i
- {
- //printf("%s\n",parr[i]);
- printf("%s\n",*(p+i));
- }
- //**p = '1111';
- //printf("%s\n",parr[0]);
-
-
- return 0;
- }
7.指针数组
- //指针数组
- //指针数组是指针还是数组 是数组,是存放指针的数组 数组我们已经知道整形数组,字符数组
- //整型数组 -存放整型的数组 字符数组 - 存放字符的数组 指针数组-存放指针(地址)的数组
-
- int main()
- {
- // char arr[] = "abcdef";
- // printf("%s\n",arr);
- int arr1[] = {1,2,3,4,5};
- int arr2[] = {2,3,4,5,6};
- int arr3[] = {3,4,5,6,7};
- //指针数组
- int* parr[] = {arr1, arr2, arr3};
- int i = 0;
- for(i = 0;i<3;i++)
- {
- int j = 0;
- for(j = 0;j <5;j++)
- {
- //printf("%d ",parr[i+j]);//err
- printf("%d ",*(parr[i]) + j);
- // printf("%d ",parr[i][j]);
- }
- printf("\n");
- }
-
- return 0;
- }