理解第一篇

上完大学不是我吹(仅仅说我认识的本学校本专业)估计很明白指针的人绝对不超过百分之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. Spring Security 源码分析 --- WebSecurity

    概述 spring security 源码分析系列文章. 源码分析 我们想一下,我们使用 ss 框架的步骤是怎么样的. @Configuration @EnableWebSecurity @Enabl ...

  2. mcast_get_loop函数

    #include <errno.h> #include <net/if.h> #include <sys/socket.h> #include <netine ...

  3. 数据库单,多,全库、冷热备份思路及备份与还原(mysqldump)

    热备份:服务开启状态下进行备份, 冷备份:服务关闭状态进行备份, 冷备份 数据库原有内容如下: MariaDB [(none)]> show databases;+--------------- ...

  4. [linux] ARCH LINUX 常见问题及实用工具汇总

    1.办公 screen-recorder 1)深度linux桌面录制软件(不支持录音),操作简单,可以保存mp4和gif格式 2)命令安装:sudo pacman -S deepin-screen-r ...

  5. 顾家办公两不误,容智ibot帮你实现高效居家办公

    春节假期结束,大部分企业已陆续开始复工.经调查显示,受新型冠状病毒疫情影响,不少企业开放了员工“在家办公“模式,就此,员工被动“SOHO”,在家办公火了. 2020 在家办公靠谱吗?会不会成为未来的趋 ...

  6. accordion(折叠面板)的使用

    一.前言: 折叠面板(accordion)允许使用多面板(panel),同时显示一个或多个面板(panel).每个面板(panel)都有展开和折叠的内建支持.点击面板(panel)头部可展开或折叠面板 ...

  7. 在工业派上使用opencv库的记录

    1.在工业派linux操作系统环境下,调用OpenCV库,用python写了第一个查看图片的程序 注意:要进入工业派的terminal 参考:https://www.cnblogs.com/magic ...

  8. cemtos安装python

    mkdir python3cd python3/yum -y install gcc*yum install zlib-devel bzip2-devel openssl-devel ncurses- ...

  9. history路由

    class HistoryRouter{ constructor(){ //用于存储不同path值对应的回调函数 this.routers = {}; this.listenPopState(); t ...

  10. web打开本地文件并读取内容

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...