首页 > 知识百科 > 正文

【C语言】指针初阶 原创

正文开始之前,我们要记住一个东西就是:地址=铲

目录

一、指针的解释二、指针指针和地址1、取地址操作符2、指针指针和解引用操作1、指针指针2、指针指针3、解引用操作符4、注意事项 3、指针变量的大小 4、指针的解引用 5、void*指针 三、指针的伤害 1、指针±指针 2、指针 - 指针 3、指针的关系 四、野指针 1、野指针形成的原因2、指针越界访问3、指针指向的空间释放五、const 修饰指针1、const 修饰指针2、const 修饰指针指针

一、指针的解释

通俗的话就是一个数据的位置。因为数据的存储是需要空间的,这个空间就有一个地址,铲子就是用来存放这个地址的,方便后续快速的访问

二、指针变量和地址

1、取地址操作符

在C语⾔中变量创建就是向内存申请空间

#include int main(){ int a = 10; 返回 0;}


我们在内存里可以看到在创建变量a的时候申请了一个空间
我们取地址a之后将地址四行显示,在这个地址里发现一个存储,0a就是十六休息下的10
这里我们介绍一下我们的老朋友,&操作符。在之前的学习中,我们在学习scanf函数的时候接触过这个操作符,这个操作符就叫取地址操作符

&a取出一个所占的四个字节中地址最小的字节地址,通过计算机的一套算法,把这个数据整形,会取出剩余的三共个地址

(此时我们对scanf函数的理解也深一个层次

 scanf("%d", &a);

这里的&a就是取出一个的地址,将里边的值进行修改)

2、支架指针和解引用操作

1、铲斗变量

那我们通过取地址操作符(&)得到的地址是一个数值,这个数值有时候需要存储起来,一批便数学再使用用户,我们把这样的地址值放在铲指针中。

#包括 int main()< /span>{ int a =< /span> 10; int *pa = &a;< /span>//这样就可以把挖出来的一个地址放到硬盘pa中了 返回 0;}

铲子手表也是手表,专门用于存放地址,存放在其中的价值都会被认为是地址

2、拆解铲子类型

 int a = 10; int *pa = &a;

*说明pa是指针指针,int说明pa这个指针指针指向的是一个int类型完整类型的对象
当然如果是short类型的对象那么就

  i = 10 ; *pi = &i;< /code>

char类型那么就

char j = 10;char< /span> * pj = &j;

3、解引用操作符

#include int main(){ int a = 10; int * pa = &a; *pa = 20; 返回 0;}

这样就把a的值更改为20了

4、注意事项

int*paint *paint* paint * pa 

这几个是一样的,表达上没有任何区别

3、指针指针的大小

#include int main(){  printf("%zd\n", sizeof(char *)); printf("%zd\n", sizeof< span class="a3b5-c06b-53ae-ab88 token punctuation">( * )); printf("%zd\n", sizeof(int * )); printf("%zd\n", sizeof( *)); 返回 0;}

指针变量的大小取决于地址的大小,指针变量的大小和类型是⽆关系,只要指针指针类型的变量在相同的平台下,大小都是相同的

4、指针的解引用

#包括 int main(){ int n = 0x12345678 ; int *pi = &n; *pi = 0; printf("%d",n): 返回 0 ;}
#include  int main( ){ int n = 0x12345678; char *pi =(< span class="b3e0-56e2-e6cf-ea18 token 关键字">char*)  &n; //强制转化,否则是不可以用char类型的猎人来接受int类型的变量的 *pi = 0;  printf("%d"< span class="53ae-ab88-888a-b3e0 token punctuation">,n); return 0;}

第一个运行结果

第二个运行结果


这说明char类型和int类型的访问权限不同,char类型可以访问一个字节,恢复十六下的八个数,int类型可以访问四个字节,恢复十六下的八个

5 、void*指针

⽆具体类型的指针,也叫泛型指针,可以接受任何类型的地址
但它不能够进行解引用操作,以及指针±整数的伤害(说起来)

三、剪刀的进攻

1、指针±整数

#包括 int< /span> main(){int arr[10] = { 1,2 3456 ,7,8910< /span> };int* p = &arr[< /span>0];int i = 0;int sz = sizeof(arr / sizeof(arr[0]);对于 (i = 0; i < sz; i++) {printf(< /跨度><跨度class="56e2-e6cf-ea18-5b7e token string">"%d", *(p + i));//p+i 这⾥就是指针+整数}< /span>返回 0;}

这里的指针经过加减后是通过单位进行访问的,那么如果是int类型,那么指针就加了四个字节,char加一个字节,short加两个字节。

2、指针 - 指针

#include < /span>int my_strlen(char* s){char * p = s;while (*p != '\0')// \0 之前的元素为字符串中的元素p++;return< /span> p - s;}int main(){printf("%d\n"  my_strlen("abc")); 返回 0;}

这样就可以算出字符串中的元素个数

3、铲子的关系软骨

< pre>#include int main(){int arr[10] = { 1,2,3,4,5< span class="6317-3403-a3b5-c06b token punctuation">,6 7,8,9,< /span>10 };int* p = &arr[0];int i = 0 span>;int sz = sizeof(arr) / sizeof(arr[0]); while (p < arr + sz) //指针的最大⼩⽐较{printf("%d "< /span>, *p);p++;} 返回 0;}

四、野铲

1、野铲形成的原因

#include int main(){int* p;//局部指针指针未初始化,默认为随机值*p = 20;返回 0;}

2、指针越界访问

# 包括 int main(){int arr[10] = {//当指针指向的范围超出配额arr的范围时,p就是野指针*(p++) = i;}返回 0;}

3、指针指向的空间释放

#< span class="6bc6-2c79-6317-3403 token 指令关键字">包括 int * 测试(){int n = 100;返回 &n;}int main (){< /span>int* p = 测试();printf("%d\n"< span class="6bc6-2c79-6317-3403 token punctuation">, *p);返回 0;}

这些原因其实很常见,也很有规矩,看一下就能看出来是理所应当的,没啥需要解释的
想办法规避它们就行了

五、const 修饰指针

1、const 修饰变量

#include < span class="56e2-e6cf-ea18-5b7e token string">int main< span class="5b7e-4f8a-4188-6a2b token punctuation">(){int m = 0 ;m = 20;//m是可以修改的const int n = 0;n = 20;//n是不能被修改的返回 0 ;}

被const修饰的变量是不能修改的

2、const修饰指针变量

int * p< span class="56e2-e6cf-ea18-5b7e token punctuation">;//没有const修饰const int * p;//const放在*的左边做修饰int  const * p;//const 放在*的左边做修饰int * const p ;//const放在*的右边做修饰

第二行和第三行实际上是一样的。
我的理解是看const修饰的量,被其修饰的量是不能改变的,我们先看第二行和第三行代码,*p不能改变,*p是指针值,指针指向指针的内容的内容,是不能够改变的,但是p指针地址,指针本身,是可以改变的。
第四行代码,const修饰符p,地址,指针本身,是不能改变的,但指针指向的变量的内容是不能改变的

分享到这里了~

【C语言】指针初阶 原创由知识百科栏目发布,感谢您对的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【C语言】指针初阶 原创

Copyright © 2012-2023 普诚元亨工作室 版权所有

*本站部分网页素材及相关资源来源互联网,如有侵权请速告知,我们将会在24小时内删除*

Z-BlogPHP 1.7.3 琼ICP备2022020219号