理解第一篇

上完大学不是我吹(仅仅说我认识的本学校本专业)估计很明白指针的人绝对不超过百分之50,学校low不low另说(因为问他们讲得断断续续的自己也说不明白,只知道那样可以用) 学链表树形结构.......等结构的时候一直困扰一个问题 例如int* a 和int  *a  ,*a,**a,int**a  或者说*******a  或者说Node n 和Node *n到底什么意思?大家都知道这是指针 ,指针本质是什么都说是地址.每次编程的时候都是报错了才能发现指针错误再去改正其实就是不太理解

例子 1

void Functionc()
{
int** a= (int** );
printf("%d\n" ,a);
}
//结果 a仍然是5
对应汇编指令 可以看到只是把5存到堆栈
00410A56 rep stos dword ptr [edi]
26: int** a= (int** )5;
00410A58 mov dword ptr [ebp-4],5
27: printf("%d\n" ,a);
00410A5F mov eax,dword ptr [ebp-4]

解: 不光是两个** 就算写成一万个星 打印结果仍然是5 因为不管是什么类型的或者你定义的结构体后面加*或者说加** 都相当于一个新的类型 


例二 & 和 * 的联系

假如你定义一个char a=10   假如你 &a 可以取到变量a的地址,你可以用char b=*a接收吗?不可以  !因为 &a 相当于 char* 类型的

那么假如char* b=&a  那么&b 是什么类型的? 对他是char** 类型的  每次加一个取地址符号就相当于类型后加个*

&取地址符条件 常量无法使用其他貌似都可以


例三

int* a 和int  *a 没有任何区别!!我们好多书上写第二种 其实第一种看的比较清楚  第二种代码比较好看

例如 int* x   其中x 和*x 区别 x 是int* 类型的,*x是 int 类型的 同理 int**  y    y是int**类型的 *y 是int*类型的 **y是int 类型的

 

前面可以用*x的条件 他的类型必须是个指针类型意思就是带一个或多个*

从汇编角度理解*p的意思如图

把10赋值给了堆栈   x值存储到【ebp-4】的地址   然而px把 ebp-4的值存到了【ebp-8】  相当于把 指向x的指针(地址)存到了【ebp-8】,

下面的int x1 =*px   把指向x的指针(地址)取出来放到ecx 又把指针指向的值(10)放到了 edx ,又把edx 放到了 【ebp-c】所在内存地址


 一个用指针找数组问题

     int arr[]={,,,};
int* px=arr;
for(int i=;i<=;i++)
{
printf("%d\n" ,*(px++));
}

都知道能打印出来1 2 3 4 都知道指针后移动一个本质是这样的

首先了解这段代码

functionss()
{
int* a;
a=(int*);
printf("%d\n" ,a++);
}

你以为输出101吗其实输出 104 ,那如果是char 类型输出多少 是101 short 呢?102 

如果是一个* 就相当于加上那个类型(意思是相当于砍掉一个*所占字节数 如果是int** 的一个变量相加要看int* 所占字节)所占用字节数 (+1的情况 如果加2 的话就是 2*所占字节数)

【int** short** 所有** 所占的都是四字节】 这个说的不大明白.......不理解也没事

进入正题

int arr[5]={1,2,3,4};
int* px=arr;
for(int i=0;i<=3;i++)
{
printf("%d\n" ,*(px++));
}
为什么 px++ 能准确找到下一个数组值村的数呢? 数组里面的值是连续存放的大家都知道 ..... px 为int* 类型 这里px++加的时候相当于 加上4 内存里加上四刚好是下一个数的地址 *px 相当于取出px地址里面的值显示出来

指针数组
void funcs()
{
int a=1;
int b=2;
int c=13;
int* arr[5]={&a,&b,&c};// 指针数组占用20个字节 (int)4*5 数组里面只能存放int* 类型数据 char* keyword[] = {"if","for","whille"};//这样也能赋值 因为这里面的数据存在常量区(没法改) 这里面存的是地址 }


唯一要记住的就是int* 数组里面存的也是int* 类型的就行 char* a[] 数组里面存的是char* 类型的 其实说白了汇编里面都是地址


*( ) 可以和[ ]互换

void funcs1()
{
char* a="nihaoya";
printf("%c \n",a[]);//输出n char** b=&a;
printf("%c \n",b[][]);//输出n b[0][1]输出i //出现这个情况原因是b[0]==a 再[]一下是取出一个字符 }

同理一个* 可以用p【 】 三个*可以用p【】【】【】来遍历


数组指针(认为很难理解的一种)

int main(int argc, char* argv[])
{ int arr[]={,,,,,,,,,,,,,,,};
int (*px)[]; //数组指针
px=(int (*)[])arr;
printf("%d \n",px);//*px和px值一样但是进行运算时宽度不一样 *px为数组类型 *px为数组首地址
printf("%d \n",*px);//*px和px值一样 但是进行运算时宽度不一样 *px为数组类型 *px为数组首地址 printf("%d \n",**(px+));// px时这里加了8字节 一个int 占四字节相当于后移两位 输出3
printf("%d \n",*(*px+));// *px为数组首地址 这里加一就下移动一位 输出 2
printf("%d \n",*(*(px+)+)); //自行判断 getchar();
return ;
}

总结: int (*px)[2] 里面的2(应该是写成大于0的都行)跟访问 arr[16]没有任何关系(不管arr有多大)  *px为数组首地址一定要记住

你也可以用nt (*px)[2][1] 来访问 arr[16] 此时**px 为数组首地址 

不是很常用........


下一篇结构体数组

对C/C++指针问题的彻底理解(复习1)的更多相关文章

  1. C语言重点——指针篇(一文让你完全搞懂指针)| 从内存理解指针 | 指针完全解析

    有干货.更有故事,微信搜索[编程指北]关注这个不一样的程序员,等你来撩~ 注:这篇文章好好看完一定会让你掌握好指针的本质 C语言最核心的知识就是指针,所以,这一篇的文章主题是「指针与内存模型」 说到指 ...

  2. 对指针和引用的理解(c++)

    1.指针 typedef说明一种新类型名,来代替已有类型名. a.案例:typedef char* String_t和#define String_d char *这两句在使用上的区别? 1)前者声明 ...

  3. C语言指针使用小记 (深入理解C指针 读后小记)

    最近正值过年在家,新年初一,闲暇时间无事可做便把以前看过的书籍整理了一下,顺手也把这本“深入理解C指针”的书重新读了一遍,这本书总体感觉比较简单,但是还是不免有些地方是平时没有想到过或者没有注意到的, ...

  4. 结合示例说明C++中const和指针结合时怎么理解

    在之前随笔<C++中const使用要点(一)>中简单叙述了const int*.int* const和const int* const的区别,记住三句话就能在实际运用时用对,但是看书时发现 ...

  5. 关于C语言的指针数组与指针数组的个人理解

    一.指针数组与指针数组 1,指针数组 顾名思义,即一个元素全部是指针的数组,其形式与普通数组相似,形式如 *a[N]. 在理解指针数组的使用方式前,我先来说下我个人对数组的理解. 比如一维整形数组(形 ...

  6. this指针指向的彻底理解

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  7. JavaScript中this指针指向的彻底理解

    this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象 这一点与函数中自由变量Action-varibal不同 var ...

  8. c语言函数指针的理解与使用

    1.函数指针的定义 顾名思义,函数指针就是函数的指针.它是一个指针,指向一个函数.看例子: A) char * (*fun1)(char * p1,char * p2); B) char * *fun ...

  9. C 真正理解二级指针

    本文转载自CSDN博主liaoxinmeng,做数据结构时遇到指针方面的问题,想了许久,因此我觉得很有必要复习一下二级指针及其使用 正文如下: 指针是C语言的灵魂,我想对于一级指针大家应该都很熟悉,也 ...

随机推荐

  1. JavaScript中的typeof 和instanceof

    Js中的instanceof 和typeof的区别 演示1 var v5=new Number("22"); document.write(typeof v5+"< ...

  2. disconf---分布式配置管理平台的搭建(linux版本)

    一.获取disconf的代码 地址:https://github.com/knightliao/disconf 二.搭建基础服务 ①redis,mysql,zookeeper在博主的其他博文中有相应搭 ...

  3. 「JSOI2015」子集选取

    「JSOI2015」子集选取 传送门 看到这个数据范围,就知道肯定是要找规律. 如果把集合看成一个长度为 \(n\) 的 \(01\) 串, \(0\) 表示没有这个元素, \(1\) 表示有这个元素 ...

  4. 学习JavaScript数据结构与算法---前端进阶系列

    学习建议 1.视频学习---认知 建议:在中国慕课上找"数据结构"相关的视频教程.中国大学MOOC 推荐清华大学.北京大学.浙江大学的教程,可先试看,然后根据自身的情况选择视频进行 ...

  5. Hadoop _ 疑难杂症 解决1 - WARN util.NativeCodeLoader: Unable to load native-hadoop library for your plat

    最近博主在进行Hive测试 压缩解压缩的时候 遇到了这个问题, 该问题也常出现在日常 hdfs 指令中, 在启动服务 与 hdfs dfs 执行指令的时候 : 都会显示该提示,下面描述下该问题应该如何 ...

  6. Newtonsoft.Json小记

    /*json相关*/ //http://www.cnblogs.com/hongfei/p/3593936.html string jsonObject = "{\"phone\& ...

  7. Golang redis 学习指南

    安装 我使用的是 https://github.com/go-redis/r... 这个 golang 客户端, 因此安装方式如下: go get gopkg.in/redis.v4 接着在代码中导入 ...

  8. spring整合web项目

    Web项目如何初始化SpringIOC容器 :思路:当服务启动时(tomcat),通过监听器将SpringIOC容器初始化一次(该监听器 spring-web.jar已经提供),web项目启动时 ,会 ...

  9. string和stringBuffer,stringBuilder的区别

    1,String类的内容一旦声明后是不可改变的,改变的只是其内存的指向,而StringBuffer类的对象内容是可以改变的. 2,对于StringBuffer,不能像String那样直接通过赋值的方式 ...

  10. Coursera 国内无法登陆问题

    参考: 1.Coursera登不上去 | 知乎 2.Win10如何修改hosts | 百度经验 浏览器在访问https://www.coursera.org时,出现正在等待 d3njjcbhbojbo ...