指针的详细讲解(一)
1.什么是指针
1.1指针的定义:指针是C语言中一个非常重要的概念,也是C语言的特色之一。使用指针可以对复杂数据进行处理,能对计算机的内存分配进行控制,在函数调用中使用指针还可以返回多个值。
2.编制的理解
3.指针的变量和地址
3.1 取地址操作符(&)
3.1.1定义:顾名思义,就是获取当前变量的内存地址,想要获得那个变量的地址,就用&后面跟上那个变量。
3.1.2代码详解:
#includeint main() { int n= 7; int *p; p = &n; //指针初始化,也可以写作 int *p = &n; printf("%d 的地址是 %p\n",n,p); return 0; }
3.2解引用操作符(*)
3.2.1作用:*的作用是引用指针指向的变量值,引用其实就是引用该变量的地址,“解”就是把该地址对应的东西解开,解出来,就像打开一个包裹一样,那就是该变量的值了,所以称为“解引用”。 也就是说,解引用是返回内存地址中对应的对象。
3.3指针的解引用
int main() { int a = 100; int* pa = &a; *pa = 0; return 0;
4.void*指针
4.1定义:void 指针可以指向任意类型的数据,就是说可以用任意类型的指针对 void 指针对 void 指针赋值。
注:void *可以接受不同类型的地址,但是无法直接计算。
5.指针运算
5.1指针+- 整数
#includeint main { int arr[10] = {1,2,3,4,5,6,7,8,9,10}; int *p = &arr[0]; int i = 0; int sz = sizeof(arr)/sizeof(arr[0]); for(i=0; i 5.2指针-指针
#includeint my_strlen(char *s) { char *p = s; while(*p != '\0' ) p++; return p-s; } int main() { printf("%d\n", my_strlen("abc")); return 0; } 5.3指针的关系运算
int main() { int arr[10] = {1,2,3,4,5,6,7,8,9,10}; int *p = &arr[0]; int i = 0; int sz = sizeof(arr)/sizeof(arr[0]); while(p6.const
6.1const修饰变量
#includeint main() { int m = 0; m = 20;//m是可以修改的 const int n = 0; n = 20;//n是不能被修改的 return 0; } 6.2const修饰指针变量
const int*p=&a;
//当把 const 放最前面的时候,它修饰的就是 *p,那么 *p 就不可变。*p 表示的是指针变量 p 所指向的内存单元里面的内容,此时这个内容不可变。其他的都可变,如 p 中存放的是指向的内存单元的地址,这个地址可变,即 p 的指向可变。但指向谁,谁的内容就不可变。
int*const p=&a;
//此时 const 修饰的是 p,所以 p 中存放的内存单元的地址不可变,而内存单元中的内容可变。即 p 的指向不可变,p 所指向的内存单元的内容可变。
const int*const p=&a;
//此时 *p 和 p 都被修饰了,那么 p 中存放的内存单元的地址和内存单元中的内容都不可变。
7.野指针
7.1定义:
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。
7.2野指针的规避:
1、指针初始化 (如果没有就初始化为NULL)
2、小心指针越界
3、指针指向空间释放即使其置为NULL
4、指针使用之前检查有效性 (例如:判断是否为NULL)
8.assert断言
8.1定义:C/C++ 中的 assert 是一个宏,用于在运行时检查一个条件是否为真,如果条件不满足,则运行时将终止程序的执行并输出一条错误信息。
assert(p != NULL);指针的详细讲解(二)
1.数组名
1.1定义:数组名是一个表示整个数组的标识符,它通常会被解释为一个指向数组第一个元素的指针常量(类型为指向元素类型的指针)。数组名代表的内存地址是不可变的。数组名的值是数组首元素的指针常量。数组名存放的是数组的首地址,而从数据类型上理解数组,数组又有它的数据类型,即定义时的数据类型不同,所占用的内存空间也不相同。
int arr[10] = {1,2,3,4,5,6,7,8,9,10}; int *p = &arr[0];2.一维数组传参的本质
2.1本质:数组传参本质上传递的是数组⾸元素的地址。
#includevoid test(int arr[]) { int sz2 = sizeof(arr)/sizeof(arr[0]); printf("sz2 = %d\n", sz2); } int main() { int arr[10] = {1,2,3,4,5,6,7,8,9,10}; int sz1 = sizeof(arr)/sizeof(arr[0]); printf("sz1 = %d\n", sz1); test(arr); return 0; } 3.二级指针
3.1定义:是一个指针变量,指向一个一级指针,并保存该一级指针的地址。
int *p = &a; int** s = &p;指针的详细讲解(三)
1.字符指针变量
1.1定义:字符指针:指向字符型数据的指针变量。每个字符串在内存中都占用一段连续的存储空间,并有唯一确定的首地址。即将字符串的首地址赋值给字符指针,可让字符指针指向一个字符串。
int main() { const char* pstr = "hello bit."; printf("%s\n", pstr); return 0; }2.数组指针变量
2.1定义:数组指针,顾名思义,就是指向数组的指针。
我们是这样定义它的:int(* p)[n] = { }; (n为要定义的个数)
int (*p)[10];3.函数指针变量
3.1定义:所谓函数指针即定义一个指向函数的指针变量
参照代码:
int (*p)(int x, int y); //参数名可以去掉,并且通常都是去掉的。 这样指针p就可以保存函数类型为两个整型参数,返回值是整型的函数地址了。希望大家看到这里已经有所收获,谢谢大家的观看,一键三连哦!!!!