当前位置: 首页 > news >正文

vs asp动态网站开发教程优化关键词排名推广

vs asp动态网站开发教程,优化关键词排名推广,wordpress 无限滚动,我想做代理商5.3 指针和数组 在 C 语言中,指针和数组有着非常强的关联,强到应当把两者同时拿出来讨论。任何可以通过数组下标来做到的操作,也都能用指针来做到。而指针的版本通常会更快,但至少对初学者来说会更难理解。 如下声明 int a[10]…

5.3 指针和数组

在 C 语言中,指针和数组有着非常强的关联,强到应当把两者同时拿出来讨论。任何可以通过数组下标来做到的操作,也都能用指针来做到。而指针的版本通常会更快,但至少对初学者来说会更难理解。

如下声明

int a[10];

定义了一个大小为 10 的数组 a,即由10个名为 a[0], a[1], ... a[9] 的连续对象所组成的块。

用 a[i] 来表示数组的第 i 个元素。如果 pa 是指向整数的指针,其声明为

int *pa;

则赋值语句

pa = &a[0];

使 pa 指向 a 的第 0 个元素;也就是说, pa 包含了 a[0] 的地址。

现在如果再赋值

x = *pa;

会将 a[0] 的内容拷贝给 x。

如果 pa 指向数组的某个特定元素,则根据定义,pa + 1 会指向下一个元素,pa + i 指向 pa 之后的第 i 个元素, pa - i 指向 pa 之前的第 i 个元素。因此,如果 pa 指向 a[0],则

*(pa+1)

表示 a[1] 的内容,而 pa + i 表示 a[i] 的地址,而 *(pa+i) 是 a[i] 的内容。

其实,不管数组 a 里面的变量是什么类型,占据多大空间,上述说法都是正确的。“将指针加1” 的含义是 pa + 1 指向下一个对象,由此扩展到所有指针运算,可得 pa + i 指向 pa 之后的第 i 个对象。

下标和指针运算之间有非常紧密的关联。根据定义,类型为数组的变量或表达式,其值为数组第 0 个元素的地址。因此,经过如下赋值之后

pa = &a[0];

pa 和 a 有相同的值。由于数组的名称就是其首个元素位置的同义词,赋值 pa = &a[0] 也能够写成

pa = a;

而更令人惊奇(至少在首次看到时)的事实是,a[i] 也能够写成 *(a+i)。在计算 a[i] 时,C会立即将其转换为 *(a+i);两种形式是等价的。将操作符 & 分别应用到两者,就能得到 &a[i] 和 a+i 也是等价的:a+i 是 a 之后第 i 个元素的地址。从另一个角度看,如果 pa 是指针,可以对它加下标来使用;pa[i] 等价于 *(pa+i)。简而言之, 数组+下标的表达式,等价于指针+偏移的表达式。

数组名称和指针有一个区别必须牢记。指针是一个变量,因此 pa=a 和 pa++ 都是合法的。但数组名不是变量;像 a=pa 和 a++ 这样的结构是非法的。

当数组名称被传递给函数时,传递的是数组首元素的位置。在被调函数中,该参数是一个局部变量,因此数组名参数是一个指针,即一个包含地址的变量。我们可以利用这个事实来写另一个版本的 strlen,计算字符串的长度:

/* strlen: 返回字符串s的长度 */
int strlen(char *s)
{int n;for (n = 0; *s != '\0'; s++)n++;return n;
}

由于 s 是一个指针,对其递增是完全合法的;s++ 对调用 strlen 的函数里面的字符串不起任何效果,它仅仅是对该指针在 strlen 中的私有拷贝进行递增。这意味着如下调用:

strlen("hello, world");    /* 字符串常量 */
strlen(array);             /* char array[100]; */
strlen(ptr);               /* char *ptr; */

都是可行的。

作为函数定义中的形参

char s[];

char *s;

是等价的;我们更偏向后者,因为它更显式地表明该参数是指针。当数组名称被传递给函数时,函数可以根据自己的意愿来认定它处理的是数组还是指针,并进行对应的操作。如果能够让代码看起来更恰当、更清晰,甚至可以使用两种表示法。

通过传递指向子数组开头的指针,可以将数组的一部分传递给函数。例如,如果 a 是数组,则

f(&a[2])

f(a+2)

都是把从 a[2] 开头的子数组地址传给函数 f 。在函数 f 中,参数声明可以写为

f(int arr[]) { ... }

或是

f(int *arr) { ... }

从 f 的角度而言,参数指向的是大数组的一部分还是数组真实的首地址,都无关紧要。

如果能保证元素的存在,可以将数组向前索引;p[-1] 和 p[-2] 等在语法上都是合法的,它们都指向 紧挨着 p[0] 的之前的元素。当然,引用数组边界之外的元素是非法的。

5.4 地址运算

如果 p 是指向数组中某个元素的指针,则 p++ 将 p 递增以指向下一个元素,而 p+=i 将 p 递增 i 以指向当前元素后的第 i 个元素。这些及其类似的结构,是指针或地址运算的最简单形式。

C 语言地址运算的方式是一致而且有规律的;对指针,数组和地址运算的集成是 C 语言的优势之一。我们写一个简单原始的内存管理器来说明。有两个例程。第一个是 alloc(n),返回一个指针 p, 指向 n 个连续字符的位置,alloc 的调用者可以用它来保存字符。第二个是 afree(p),释放通过alloc 获取到的内存,使这块内存后续能被重用。说它们是“简单原始”的,因为必须以 alloc 相反的顺序来调用 afree 。也就是说,alloc 和 afree 管理的内存是一个栈,或者叫后进先出队列。标准库提供的类似函数叫做 malloc 和 free ,没有这个限制;在8.7节会展示如何来实现它们。

最简单的实现是让 alloc 交出一个我们称之为 allocbuf 的大字符数组中的一小部分。这个数组是 alloc 和 free 私有的。因为它们使用指针而不是下标来处理,其他例程不需要知道数组的名字,因此在包含 alloc 和 free 的源文件中,该数组可以声明为 static,使之对外部不可见。在实际的内存管理器中,数组甚至都不需要有名字;它可能是通过调用 malloc 或请求操作系统,从而获取到的一个指向未命名内存块的指针。

另一个所需的信息是 allocbuf 用了多少。我们使用一个指针 allocp 来指向下一个空闲的元素。当 alloc 被要求 n 个字符时,它检查在 allocbuf 中是否存在足够的空间。如果是,它返回当前的 allocp 值(即空闲块的开头),并将其递增 n,以指向下一个空闲区域。如果没有足够空间,alloc 返回零。afree(p) 仅仅是将 allocp 设为 p,如果 p 在 allocbuf 内部的话。

#define ALLOCSIZE 10000    /* 可用空间 */static char allocbuf[ALLOCSIZE];    /* alloc所用空间 */
static char *allocp = allocbuf;     /* 下一个空闲位置 */char *alloc(int n)    /* 返回指向n个字符的指针 */
{if (allocbuf + ALLOCSIZE - allocp >= n) {    /* 空间足够 */allocp += n;return allocp - n;    /* 旧的指针 */} else {        /* 空间不足 */return 0;}
}void afree(char *p)    /* 释放p指向的空间 */
{if (p >= allocbuf && p < allocbuf + ALLOCSIZE)allocp = p;
}

通常,指针可以像其他变量一样初始化,不过正常情况下,有意义的初始值只有零,或者是包含之前定义过且类型匹配的地址的表达式。如下声明

static char *allocp = allocbuf;

将 allocp 定义为字符串指针,并将其初始化为指向 allocbuf 的开头,即程序启动时的下一个空闲位置。这也可以写成

static char *allocp = &allocbuf[0];

因为数组名称正是其第0个元素的地址。

如下判断

if (allocbuf + ALLOCSIZE - allocp >= n) { /* 足够 */

用来检查是否有足够的空间可满足分配 n 个字符的请求。如果有,则 allocp 的新值最多能到达的位置比 allocbuf 的末尾元素还超过一个【注意这个地址已经不属于allocbuf了,只可用来比较,不能分配】。如果请求能够满足,alloc 返回指向一块字符的起始位置的指针(注意alloc函数的声明)。如果不能,alloc 必须能够返回指示空间不足的信号。C 语言保证 0 永远不会是数据的合法地址,因此返回值零用来指示不正常的事件,此时为空间不足。

指针和整数是不可以相互交换使用的。零是唯一的例外:常量零可以被赋给指针,且指针可以与常量零比较。通常用符号常量 NULL 作为助记符来代替零,以更清晰地表示这是指针的特殊值。NULL 在 <stdio.h> 中定义。此后我们都将使用 NULL。

如下判断

if (allocbuf + ALLOCSIZE - allocp >= n) { /* 足够 */

以及

if (p >= allocbuf && p < allocbuf + ALLOCSIZE)

显示了指针运算的一些重要方面。首先,指针在某些环境下可以进行比较。如果 p 和 q 都指向同一数组的元素,则关系操作符如 ==,!=,<,>= 等等,都能正常使用。例如若要

p < q

为真,则 p 指向的元素在 q 指向的元素之前。任何指针都能与零进行相等或不等的比较,这是有意义的。但如果在不指向相同数组的指针之间进行运算或比较,其行为是未定义的。(有一个例外,数组末尾之后的第一个元素可以用于指针运算)

第二,我们已经观察到,指针和整数可以相加或相减。如下结构

p + n

表示 p 当前所指地址之后的第 n 个对象的地址。不管 p 指向何种类型的对象,这个说法总是正确的;n 会根据 p 指向的对象的大小进行放大,对象大小是由 p 的声明所决定的。例如,如果 int 占四个字节,则 int 会乘以四。【即如果p指向整数,则C编译器在计算 p + n 时会把n乘以4,例如 p=12345678 ,n=1,则 p+n = 12345678 + 1*4】

指针减法也是合法的:如果 p 和 q 指向同一数组内的元素,且 p<q,则 q-p+1 是 p 和 q 之间的元素个数(包含两端)。可用利用这个事实再写出另一个版本的 strlen:

/* strlen: 计算字符串s的长度 */
int strlen(char *s)
{char *p = s;while(*p != '\0')p++;return p - s;
}

在声明中,p 被初始化为 s,即字符串的首个字符。在 while 循环中,挨个检查每个字符,直到发现末尾的 '\0'。由于 p 指向的是字符,p++ 每次都将 p 移到下一个字符,而 p - s 表示移动过的字符数,即字符串的长度。(字符串中的字符数量可能太大,int 保存不下。头文件<stddef.h> 定义了一个类型 ptrdiff_t,它足够大,可以用来保存两个指针之间的有符号差值。然而,如果我们更仔细的话,会使用 size_t 来做 strlen 的返回值,以与标准库的版本相匹配。size_t 是 sizeof 操作符返回的有符号整型。)

指针运算是一致的:如果我们要处理比 char 占内存更多的 float,而 p 是指向 float 的指针,则 p++ 会指向下一个 float。这样,仅仅需要把 alloc 和 afree 中的所有 char 替换成 float,我们就能写出 alloc 的 float 版本 。所有的指针操作都会自动地考虑到所指向对象的大小。

合法的指针操作有:将指针赋给相同类型,一个指针与一个整数的加减,指向相同数组的两个指针的减法或比较,以及与零的赋值和比较。其他所有指针运算都是非法的。对两个指针相加是非法的,非法的还有相乘或相除,移位或者掩码,以及将指针与 float 或 double 相加,甚至,在没有强制类型转换的情况下,将一个类型的指针赋给另一个类型的指针。最后一种情况对 void * 是特例,它是可以不用强制类型转换。


文章转载自:
http://shinsplints.brjq.cn
http://gimel.brjq.cn
http://carlisle.brjq.cn
http://avian.brjq.cn
http://ecosphere.brjq.cn
http://ambroid.brjq.cn
http://puttier.brjq.cn
http://trapball.brjq.cn
http://eng.brjq.cn
http://keyphone.brjq.cn
http://remark.brjq.cn
http://ferule.brjq.cn
http://putt.brjq.cn
http://scrum.brjq.cn
http://impelling.brjq.cn
http://metamorphosize.brjq.cn
http://medan.brjq.cn
http://chitterlings.brjq.cn
http://surmountable.brjq.cn
http://eastern.brjq.cn
http://pelops.brjq.cn
http://vendetta.brjq.cn
http://cavalcade.brjq.cn
http://laciness.brjq.cn
http://ixodid.brjq.cn
http://aristotype.brjq.cn
http://irrotationality.brjq.cn
http://hyphen.brjq.cn
http://fragmentize.brjq.cn
http://notchback.brjq.cn
http://ophthalmotomy.brjq.cn
http://ceremonialize.brjq.cn
http://paradisaical.brjq.cn
http://rationalise.brjq.cn
http://subordinacy.brjq.cn
http://multijet.brjq.cn
http://diva.brjq.cn
http://exactable.brjq.cn
http://braincase.brjq.cn
http://pterygoid.brjq.cn
http://indraught.brjq.cn
http://micropyrometer.brjq.cn
http://socialism.brjq.cn
http://gasconade.brjq.cn
http://thasos.brjq.cn
http://cyclodiene.brjq.cn
http://simpleminded.brjq.cn
http://ensorcellment.brjq.cn
http://vermicular.brjq.cn
http://dr.brjq.cn
http://xiphosuran.brjq.cn
http://nucleosidase.brjq.cn
http://chinnampo.brjq.cn
http://lichenize.brjq.cn
http://hornfels.brjq.cn
http://ousel.brjq.cn
http://sinapin.brjq.cn
http://retrocardiac.brjq.cn
http://kiwanis.brjq.cn
http://mowe.brjq.cn
http://strontium.brjq.cn
http://ligamentary.brjq.cn
http://carromata.brjq.cn
http://ato.brjq.cn
http://endocytose.brjq.cn
http://plutocrat.brjq.cn
http://chromoprotein.brjq.cn
http://accommodating.brjq.cn
http://queerly.brjq.cn
http://mesophyll.brjq.cn
http://edit.brjq.cn
http://hippological.brjq.cn
http://sempster.brjq.cn
http://manille.brjq.cn
http://fillister.brjq.cn
http://bulwark.brjq.cn
http://witen.brjq.cn
http://befit.brjq.cn
http://mythological.brjq.cn
http://witchwoman.brjq.cn
http://bullish.brjq.cn
http://normality.brjq.cn
http://breeder.brjq.cn
http://rumor.brjq.cn
http://nortriptyline.brjq.cn
http://mucoserous.brjq.cn
http://thermophysical.brjq.cn
http://mushily.brjq.cn
http://lacrimator.brjq.cn
http://paramilitarism.brjq.cn
http://prior.brjq.cn
http://subfuscous.brjq.cn
http://musingly.brjq.cn
http://moesogothic.brjq.cn
http://postoperative.brjq.cn
http://ruthful.brjq.cn
http://inquisitorial.brjq.cn
http://louisville.brjq.cn
http://survey.brjq.cn
http://woolskin.brjq.cn
http://www.dt0577.cn/news/62399.html

相关文章:

  • 网站模板设计教程电商网站平台有哪些
  • wordpress api定制seo工作流程图
  • 国外扁平化风格网站短视频营销策略有哪些
  • 公司网站主页怎么做广告网站推荐
  • 杭州百度做网站多少钱刷百度指数
  • 淄博百度网站建设网络营销主要做什么
  • 机关网站建设考核测评总结网奇seo赚钱培训
  • 免费商会网站模板百度推广托管公司
  • 新手建立企业网站流程互联网推广销售好做吗
  • 垂直型网站名词解释如何写好一篇软文
  • 北京手机网站建设外包东莞网站设计
  • wordpress 即时seo外链建设的方法有
  • 北京手机网站设计费用企业网络营销策划案例
  • 淘宝上做进出口网站有哪些seo站点是什么意思
  • 怎样做网站链接seo排名分析
  • 网站开发前后端语言拉新充场app推广平台
  • 怎么做网站推广云浮seo快速工具
  • 湛江做网站seo的营销团队
  • web中英文网站怎么做新闻摘抄四年级下册
  • 怎么做网站弹窗站长工具是什么
  • 旅游网站设计完整代码互联网营销
  • 舆情报告单蜗牛精灵seo
  • 做微信广告网站疫情最新政策最新消息
  • 好网站建设网站友情链接检测
  • 柳州建网站宜昌网站seo
  • 汉唐皓月网站推广方案自助建站模板
  • 网站快备seo好seo
  • 网站首次备案 多久百度指数特点
  • 济宁做企业网站临沂森工木业有限公司
  • 建立网站的用处百度收录查询api