网站开发需求目标,椒江住房和城乡建设规划局网站,首页无法删除wordpress,微网站开发周期文章目录 一、指针的运算#xff08;1#xff09;指针加整数#xff08;2#xff09;指针减指针#xff08;指针关系运算#xff09; 二、野指针#xff08;1#xff09;野指针的成因#xff08;1.1#xff09;指针未初始化#xff08;1.2#xff09;指针的越界访问… 文章目录 一、指针的运算1指针加整数2指针减指针指针关系运算 二、野指针1野指针的成因1.1指针未初始化1.2指针的越界访问1.3指针指向的空间释放 2如何避免野指针2.1指针需要初始化2.2指针变量不再使用时及时置NULL指针使用之前检查有效性 三、 strlen的模拟实现四、总结 一、指针的运算
1指针加整数
例子我们打印一组数字
#includestdio.h
int main()
{int arr[10] { 0,1,2,3,4,5,6,7,8,9 };int* pa arr[0];int sz sizeof(arr) / sizeof(arr[0]);for (int i 0; i sz; i){printf(%d , *(pa i));}return 0;
} 这里的pa i就是指针变量加上一个整数pa i是地址*是对这个地址的解引用。
2指针减指针指针关系运算
#includestdio.h
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10};int* pa arr[0];printf(%d , arr[9] - pa);return 0;
} 上面的代码我们也可以用指针关系运算来写这里我们需要用到循环
#includestdio.h
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int* pa arr[0];int sz sizeof(arr) / sizeof(arr[0]);while (pa arrsz){printf(%d , *pa);pa;}return 0;
}这里的pa arrsz是指针的比较pa就是第一个元素开始的地址而arrsz就是最后一个元素结束的地址 这里的arr[9] - pa也可以写成arr[9]-arr[0]而得到的结果是 9 。由此我们可以得到一个结论 指针的关系运算得到的是指针和指针之间元素的个数。
二、野指针
1野指针的成因
1.1指针未初始化
示范一个错误例子
#includestdio.hint main()
{int* pa;*pa 1;printf(%d , *pa);return 0;
}局部变量指针未初始化默认为随机值。
1.2指针的越界访问
#includestdio.h
int main()
{int arr[10] { 0 };int* pa arr[0];for (int i 0; i 11; i){*(pa) i;printf(%d , *pa);}return 0;
}
指针指向的范围超出数组arr的范围pa就是野指针指针指向的范围有11个而数组arr的范围只有10个 1.3指针指向的空间释放
#includestdio.h
int Print()
{int a 90;return a;
}
int main()
{int* pa Print();printf(%d , *pa);return 0;
}我们写一个函数将a赋值为90然后把a的空间返回到主函数中*pa可以接受到a的地址但是出了Print()函数空间就被回收了此时*pa带着地址去访问该空间不会得到任何数字这就是空间的释放。
2如何避免野指针
2.1指针需要初始化 如果我们明确知道指针指向哪里就直接赋值地址
#includestdio.h
int main()
{int a 20;int* pa a;return 0;
}这里前面就是知道pa指针指向的是a的地址所以我们直接int* pa a。 如果我们不知道指针应该指向哪里可以给指针赋值NULL。NULL 是C语⾔中定义的⼀个标识符常量值是00也是地址这个地址是⽆法使⽤的读写该地址会报错。
#includestdio.h
int main()
{int* p NULL;*p 20; //errprintf(%d , *p);return 0;
}小心指针的越界
⼀个程序向内存申请了哪些空间通过指针也就只能访问哪些空间不能超出范围访问超出了就是越界访问。可以见上面的1.2
2.2指针变量不再使用时及时置NULL指针使用之前检查有效性
#includestdio.h
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int* pa arr[0];for (int i 0; i 10; i){*(pa) i;}pa NULL;pa arr[0];if (pa ! NULL){for (int i 0; i 10; i){printf(%d , *(pa i));}}return 0;
}当 *(pa) i;循环结束后pa是超出了arr的范围的此时可以把pa重置当我们要重新用到pa时可以让pa重新获得地址重新获得地址后我们需要判断pa是不是空指针以确保代码的安全性。 避免返回局部变量的地址可见1.3
三、 strlen的模拟实现
库函数strlen的功能是求字符串长度统计的是字符串中 \0 之前的字符的个数。
如果要模拟实现只要从起始地址开始向后逐个字符的遍历只要不是 \0 字符计数器就1这样直到 \0 就停止。
#includestdio.h
#includestring.h
int my_strlen(char* pc)
{int count 0;while (*pc ! \0){count;pc;}return count;
}
int main()
{char arr[] { abcdf };int len my_strlen(arr);printf(%d , len);return 0;
}上面的代码我们可以发现有很多的不足之处不可以确保代码完全的安全性 如果用户不小心把数组传成了空指针 int是有符号的整形它可以为负数但是我们统计数字不可能是负数 char *pc只是用于遍历的不能对*pc进行修改 所以最后的代码应该改为
#includeassert.h
#includestdio.h
#includestring.h
size_t my_strlen( const char* pc)
{assert(pc ! NULL);size_t count 0;while (*pc ! \0){count;pc;}return count;
}
int main()
{char arr[] { abcdf };size_t len my_strlen(arr);printf(%zd , len);return 0;
}四、总结
指针需要理解的东西有很多希望大家可以自己慢慢去消化指针这一章的内容还没有结束哟希望与大家下一次再见。ԅ(¯ㅂ¯ԅ)