理解*ptr++

这是C语言中指针的基本用法之一,我们先来看一个小例子。下面是代码:

int main(void)
{
    char *p = "Hello";
    while(*p++)
        printf("%c", *p);
    return 0;
}

这段代码中第一句表达式:

char *p = "Hello";

声明了指向char类型的指针p,当我们说“指向char类型的指针”时到底是什么意思呢?实际上很简单:p的值就是一个存放char类型元素的地址,p告诉我们在内存中有这么一块地址里面存放的是char类型的变量。

这句表达式初始化了指针p,将它指向字符串“Hello”的第一个字符,对于这一点我们要时刻记住p指向的并不是整个字符串,而只是第一个字符“H”,也就是说p的值是字符串“Hello”中“H”的地址。

下面是一个循环:

while (*p++)

这里面的*p++是什么意思呢?一般初学者都会有下面的几种疑惑:

  1. 前缀++和间接取值*的优先级。
  2. 后缀自增表达式的值的情况。
  3. 后缀自增表达式的副作用。

1、优先级,快速察看一下运算符的优先级表可知后缀运算符的优先级(16)高于引用运算符(15)。也就是说*p++可以表示为*(p++),也就是说*是作用于p++的。先来看P++部分。

2、后缀表达式值,p++的值是P++表达式的P之前的值。假设你有:

int i = 7;
printf("%d\n", i++);
printf("%d\n", i);

输出将会是:

7
8

可以看到i++ 的值是i自增之前的值。那么P++也就是P自增之前的值。p中的值是“H”的地址。

接下来*P++就很简单了,*代表取出p中目前地址所存放的值,也就是“H”。

也许有同学会问,既然*p++表示“H”,那么为什么没有显示出来呢,下面就要说道副作用了。

3、后缀表达式的副作用,后缀++表达式的值是当前变量的值,但是这个表达式运算过后会有副作用。回头再看一下上面的代码和输出。

在第一个printf()函数中i++的值为7,但在C语言中会保证在下一条语句执行前的某个时刻(之所以说某个时刻是因为这个时刻和机器相关),这一条语句的副作用会产生,也就是说在第二条printf()执行前i的值一定会被加一。顺便提一下,这是C标准中少数几个有这样保证的副作用。

在最前面的代码中,当*P++执行时他指向的是字符“H”,但之后p的值加一,最终在屏幕上显示的就是ello了。

时间: 2024-10-22 22:03:07

理解*ptr++的相关文章

通解DNS(下)

当我为继续写<通解DNS(下)>的时候,我才发现,我遇到了一些难题,在解决这些问题的时候,我才理解到了DNS与之关联的技术还是比较复杂的  -丁胖胖 六.DNS中特殊的@与FQDN 在DNS设置中,@符号是一个比较特殊的符号,它用来代表ZONE,所以在如z00w00.local这样的ZONE文件中,所以在SOA中有一个"responsible mail addr"配置的地方,你不会找到@符号,但那确实是一个E-MAIL地址(图6.1) (图6.1) FQDN-Fully Q

霍夫变换理解

霍夫变换可以用于直线检测,圆检测等.我需要解决的问题是二维点云线特征提取,相关文献上说霍夫变换可以提取,决定深入学习一下. 先上两张图:直线的表达式采用极坐标表示ρ=xcosθ+ysinθ,关于ρ和θ的几何意义如图.证明下面的图可以说明. 因此过某一点A的极坐标方程可以表示所有过A点的直线族. 同理过某一点B的极坐标方程可以表示过有过点B的直线族.两个直线族的集合就是同时过A点和B点的直线. 霍夫变换首先将极坐标系的纵横坐标轴ρ和θ离散化,构成一个网格m*n的数组.这样对栅格图像的每一个非0点进

《Effective Modern C++》翻译--条款2: 理解auto自动类型推导

条款2: 理解auto自动类型推导 如果你已经读过条款1关于模板类型推导的内容,那么你几乎已经知道了关于auto类型推导的全部.至于为什么auto类型推导就是模板类型推导只有一个地方感到好奇.那是什么呢?即模板类型推导包括了模板.函数和参数,而auto类型推断不用与这些打交道. 这当然是真的,但是没关系.模板类型推导和auto自动类型推导是直接匹配的.从字面上看,就是从一个算法转换到另一个算法而已. 在条款1中,阐述模板类型推导采用的是常规的函数模板: template<typename T>

int指令理解

以下是王爽老师的<汇编语言>中第十五章中的一段程序代码,其功能是增加9号中断的功能,当按下Esc键时屏幕中显示的字母改变颜色 assume cs:codesg,ss:stack,ds:data data segment dw 0,0 data ends stack segment db 128 dup(0) stack ends codesg segment start: mov ax,data mov ds,ax mov ax,stack mov ss,ax mov sp,128 mov a

对于&quot;单链表逆置和递归&quot;的问题的理解.

一. 相关知识要点: 学习或了解基础数据结构和C语言, 对基础链表知识或相关知识有概况性认识. 例如: 本题目结构为: 1 #define elem_type int 2 3 typedef struct _single_list { 4 elem_type data; //所存的数据元素 5 _single_list *next; //所存的指针元素 6 }ListNode; 二. 问题的思考过程(本题以3种不同的方法解决): <1>类似于我们学习的C语言基础知识中的冒泡排序(参考C程序设计

字符串匹配算法KMP详细解释——深入理解

1. 前言 字符串匹配是一个经典算法问题,展开来讲各类问题多达几十种,有名称的算法也不下三十种,所以需要深入学习的东西有很多.这次我们来探讨一个最简单的问题,假设现在随机输入一个长度为m的主串T,另外输入一个长度为n(n≤m)的字符串P,我们来判断字符串P是否是主串T的一个子串(即能否从T中随机取出与P同长的一段字符串,与P完全匹配). 2. 蛮力匹配法 问题很简单,当然也有最直接.最直观也是最好想到的方法,蛮力串匹配.即两个字符串像物流传送带一般,主串固定,子串一步步像前移动,一位位匹配比较,

【转载】C/C++杂记:深入理解数据成员指针、函数成员指针

原文:C/C++杂记:深入理解数据成员指针.函数成员指针 1. 数据成员指针 对于普通指针变量来说,其值是它所指向的地址,0表示空指针.而对于数据成员指针变量来说,其值是数据成员所在地址相对于对象起始地址的偏移值,空指针用-1表示.例: 代码示例:   2. 函数成员指针 函数成员指针与普通函数指针相比,其size为普通函数指针的两倍(x64下为16字节),分为:ptr和adj两部分. (1) 非虚函数成员指针 ptr部分内容为函数指针(指向一个全局函数,该函数的第一个参数为this指针),ad

我所理解的内存分配算法(一)

内存分配从本质上来说是一种空间管理算法,给你一块连续的空间,提供存储服务,那么你的空间管理跟分配要采用什么样的算法才会比较高效? Bump-the-Pointer Bump-the-Pointer是最简单的算法.HotSpot的MM白皮书是这么描述btp的, That is, the end of the previously allocated object is always kept track of. When a new allocation request needs to be s

NS3中一些难以理解的常数

摘要:在NS3的学习中,PHY MAC中总有一些常数,需要理解才能修改.如帧间间隔等.那么,本文做个简单分析,帮助大家理解.针对802.11标准中MAC协议.   void WifiMac::Configure80211b (void) { SetSifs (MicroSeconds (10)); SetSlot (MicroSeconds (20)); SetEifsNoDifs (MicroSeconds (10 + 304)); SetPifs (MicroSeconds (10 + 20