[c/c++] _ 指针及指针的基本使用

指针是c语言的一个重要的数据类型,在C语言程序设计中,利用指针可以直接对内存中的各种不同的数据进行快速处理,同时也为函数之间各类数据的传递提供了便捷的方法,指针操作是与计算机系统内部资源密切相关的一种处理方式.


  • 地址

我们知道,一个程序一旦被执行,程序中的指令,常量,变量等都要储存在计算机内存中.计算机的内存是以字节为单位的一片连续的存储空间.每个字节都有一个编号.这个编号就称为内存地址.没有地址,没有编号.系统则无法对内存进行管理.

内存的存储空间是连续的,所以其地址(编号)也是连续的.地址与储存单元一一对应.而且是存储单元的唯一标志.需要注意的是储存单元的地址与储存单元中的内容是两回事.

我们知道,在高级语言中,变量可以直接通过变量名,变量类型来开辟一个内存空间,储存我们的变量内容,并且我们可以直接通过变量名来对该变量的内容进行操作,这是因为高级语言中,变量在声明时,就为我们创建了一张对应的表,将变量名与开辟的内存空间地址联系起来.归根结底,还是通过变量的地址来对对应的内存空间进行访问与操作的.

  • 指针变量

而c语言中则提供了这样一种变量.指针变量.指针类型的变量是用来存放地址的变量.从定义来看,指针变量是一个变量,它和普通变量一样,是占用一定内存空间的.但是它是用来存放地址的.这意味着它一般是用来对其他变量进行操作的.

当把某一个地址量赋予指针变量时,则该指针变量就指向了那个地址的内存区域.这样做的目的就是为了能够通过这种指向变量地址的方式,来实现间接对某一内存区域中存储的内容进行处理.

指针变量指向的内存区域中的数据称为指针的目标,如果它指向一个变量的内存空间,则该变量称为指针的目标变量.通过指针变量访问目标变量的方式叫间接访问方式.

指针不仅仅可以指向变量的地址,还可以指向内存中的其他任何数据结构,如数组,结构,和联合体,还可以指向函数.这将使指针能够做的事情更加强大.

在程序中参与处理的量不是指针,指针本身只是一个地址量,其指向的目标才是要处理的数据.


  • 指针的定义:

类别名 数据类型 *指针名

int *px
char *pchar
static int *pa

指针的数据类型不是指针变量本身的数据类型,而是指向目标的数据类型,因为指针变量指示用来存放其指向目标的地址,所以其类型也应当与其保持一致.

  • 指针的初始化:
int a;
int *p = &a;

&a就是一个地址常量.它就是变量a的内存地址.当将一个变量的地址赋值给一个指针时,它必须是已经声明过的(定义),因为变量的空间是动态分配的,只有预先声明了该变量.才会为其分配内存空间.

当然指针变量还可以被指向一个地址变量.也就是指针之间可以进行赋值操作.将一个指针变量赋值给另一个指正变量.

int n;
int *p = &n;
int *q = p;

看两个例子:

// 指针概念
void PointConcept(int b) {
    int a = b;
    int* pa = &a;

    printf("a:%d\n",a);
    printf("*pa:%d\n",*pa);
    printf("&a:%x(HEX)\n",&a); // %x以十六进制输出.
    printf("pa:%x(HEX)\n",pa);
    printf("&pa:%x(HEX)\n",&pa);
}
图片.png

这里可以看到,&a,pa指向的都是变量a的内存地址.而&pa指向是指针变量pa的内存地址.这说明指针变量具有与普通变量一样性质,只不过它的内存空间存放的是目标数据的地址.所以其本身的地址是不同的.


  • 指针变量的长度:
// 指针长度
void PointerLen() {
    char str[] = "abcdefg", * ps =str;
    int i = 10, * pi = &i;
    float f = 45.45, * pf = &f;
    double d = 354.33, * pd = &d;

    printf("size of str pointer is byte=%d,bit=%d\n",sizeof(ps),8*sizeof(ps));
    printf("size of str pointer is byte=%d,bit=%d\n",sizeof(pi),8*sizeof(pi));
    printf("size of str pointer is byte=%d,bit=%d\n",sizeof(pf),8*sizeof(pf));
    printf("size of str pointer is byte=%d,bit=%d\n",sizeof(pd),8*sizeof(pd));
}
图片.png

我们可以看到,四种类型的指针变量的长度都是相同的,所以指针变量的长度不是根据指针变量的类型来定的,指针变量的类型只是对应其指向目标的数据类型.

指针存放的是其指向目标的首地址,而不是其目标数据全部地址

为什么指针只需要指向目标数据的首地址,并且其类型必须要与其指向的目标数据类型保持一致呢.这就是因为内存单元的连续性,其地址都是连续,指针只需要知道指向目标的首地址,和指向目标的数据类型(相当于知道了数据长度).就可以实现完全读取到目标数据的所有内存地址了.

所以,指针变量在内存中的长度大小是不变的,4byte,32bit.只需要用来存放目标数据的首地址就可以了.


  • &(取地址运算符)和*(指针运算符)

&运算符

我们在指针的定义与初始化中了解到了,我们需要使用到*号来声明一个指针变量,使用&获取到目标变量的地址,然后赋值给指针变量.

使用&运算符操作的对象必须是左值表达式(即变量或有名存储区).

int x; // 则&x的类型就是int*(整形指针) 
char y; // 则&y的类型就是 char* (字符型指针)
double z; // &z的类型就是double* (双精度浮点型指针)

需要注意的一点是:数组,常量,不是左值表达式.而寄存器变量没有存储地址,所以他们都不能作为单目运算符&的操作对象.

int a[4];
register int k;
// 使用&a[0],&a[1]都是合法的,但是不能使用&a,&k.

指针运算符*
单目是间接访问运算符,它通过指针间接访问所指的对象.而不是通过名称访问的,所以称为间接访问.与访问对象组成的表达式,称为间接访问表达式:

* 操作对象
char a;
* (&a); // 地址表达式
*pa=&a; //地址表达式,将a变量的地址赋值给了pa,然后通过*指针符指向pa指向的本身.

操作对象必须是一个地址表达式.即指针(地址表达式,或地址常量),运算结果为指针所指的对象(变量本身).结果类型为指针所指对象的类型.

char c,*pc=&c; //变量声明且初始化了指针变量pc存放c的地址.

*pc='a'; // 通过指针符(间接访问指针变量pc所指向的c变量的内存区),赋值.
*(&c)='a'; // 直接通过指针符(间接访问c地址指向的数据内存区),赋值
c='a'; // 直接通过变量名赋值.

单目运算符*和&的运算关系

他们互为逆运算,即*指向的是指针变量的指向目标变量,&获取的是指向目标的内存地址.即:
*(&左值表达式)=左值表达式;

int c;
*(&c); //指向的就是c本身.

&(*左值表达式)=地址表达式;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容