分享好友 最新动态首页 最新动态分类 切换频道
深圳市网络营销推广品牌/关键词的优化方法
2024-12-28 19:30
  
 

除了优先级之外,下标引用和间接访问完全相同
所以 array[subscript] 和 (array + (subscript) ) 完全相同.在使用下标引用的地方,你可以使用对等的指针表达式来代替.
下标可以是负数
如:
int array[10];
int
ap = array + 2;
由于ap 指向array 的第三个元素, ap[-1] 指向 array的第二个元素.
下标越界是非法的
ap[9] 是非法的.
一个奇葩 2[array]
它是合法的,把它转换成对等的间接访问表达式,为 (2 + (array) ) ,去掉内括号,交换 array 和 2 的位置, 得 (array+ 2). 也就是array[2]

深圳市网络营销推广品牌/关键词的优化方法

  
  
 

但这里在循环每次执行的时,执行乘法运算的都是两个相同的数(1和4, 步长和整型元素长度). 结果这个乘法只是在编译时执行一次,即程序中现在包含来一条指令,把4与指针相加,程序在运行时并不执行乘法运算.

指针和数组是不相等的.
例子:
int a[5];
int *b;

  • 他们都具有指针指,他们都可以进行间接下标引用操作.
  • 区别:1)声明一个数组,编译器将根据声明所指定的元素数量为数组保留内存空间,然后再创建数组名,它的值是一个常量,指向这段空间的起始位置.声明一个指针变量时,编译器只为指针本身保留内存空间,它并不为任何整型值分配内存空间.2)指针变量并未初始化为指向任何现有的内存空间,如果它是一个自动变量,它甚至根本不会被初始化.
    所以 int b;是非法的 b 将访问内存中某个不确定的位置,或者导致程序终止. 但是b++ 可以编译通过,但是a++却不行.因为a 的值是一个常量.

当一个数组名作为参数传递给一个函数时.
数组名的值就是一个指向数组第一个元素的指针.所以此时传递给函数的是一份该指针的拷贝.
函数如果执行来下标引用,实际上是对这个指针执行间接访问操作,并且通过这种间接访问,函数可以访问和修改调用程序的数组元素.
表面上看,C语言中函数的参数都是值传递,但是参数是指针的时候为什么有变成地址传递了?这是不是矛盾?
先说结论,实际上,C中所有的函数参数都是值传递.数组名也不例外.传递的参数是一份拷贝,(指向数组起始位置的指针拷贝),所以函数可以自由地操作它的指针型参,而不必担心会修改对应的作为实参的指针.
如果传递了一个指向某个变量的指针,而函数对该指针执行了间接访问操作,那么函数就可以修改那个变量.
例子:

如果你想把一个数组名参数传递给函数,准确的函数形参应该是怎样的?它是因该声明为一个指针还是一个数组?
实际上,调用函数时实际上传递的是一个指针,所以函数的形参实际上是一个指针.编译器实际上也接受数组形式的参数.
int strlen( char *string);
int strlen( char string);
在这里,strlen的两种传参方式是一样的.

两种声明都可以,但是哪个“更加准确呢”,答案是指针. 因为实参实际上是一个指针,而不是数组. 同样,表达式 sizeof sting的值是指向字符的指针长度,而不是数组的长度.
为什么函数原型中的一维数组形参无需写明它的元素数目,因为函数并不为数组分配内存空间.形参只是一个指针,它指向的是已经在其他地方分配好内存的空间,这个事实解释了为什么数组形参可以与任何长度的数组匹配-- 它实际传递的只是数组第一个元素的指针.另一方面,这种实现方案使函数无法知道数组的长度.如果函数需要知道数组的长度,它必须作为一个显式的参数传递给函数.

比如这样,
char find_char(char source, int length, char *given);

 

静态和自动初始化
数组的初始化方式类似于标量变量的初始化方式--也就是取决于他们的存储类型.存储于静态内存的数组只初始化一次,也就是在程序开始执行之前.程序并不要执行指令把这些值放到何时的位置,他们一开始就在哪里了.这个魔术是由连接器完成的,它用包含可执行程序的文件中何时的值对数组元素进行初始化.如果数组未被初始化,数组元素的初始值将会自动设置为0. 当这个文件载入到内存中准备执行时,初始化后的数组值和程序指令一样也被载入到内存中.因此,当程序执行时,静态数组已经初始化完毕.

对于自动变量而言,初始化过程就没有那么浪漫了.因为自动变量位于运行时堆栈中,执行每次进入他们所在的代码块时,这类变量每次所处的内存位置可能并不相同.在程序开始前,编译器没有办法对这些位置进行初始化.所以自动变量在缺省情况下是未初始化的.如果自动变量的声明中给出了初始值,每次当执行流进入自动变量声明所在的作用域时,变量就被一条隐式的赋值语句初始化.这条隐式的复制语句和普通的赋值语句一样需要时间和空间来执行.数组的问题在于初始化列表中可能有很多值,这就可能产生许多条复制语句.对于那些非常盘大的数组,它的初始化时间可能非常可观.
如果数组初始化位于局部于一个函数时,你因该仔细考虑一下,在程序的执行流每次进入函数时,每次都对数组进行初始化是不是值得,如果不值得,就把数组声明为static.这样改变数组的存储区为静态区,只需在程序开始前执行一次.

int vector[] = {1, 2, 3, 4, 5};
如果声明中并未给出数组的长度,编译器就把数组的长度设置为刚好能够容纳所有的初始值的长度. 如果初始值列表经常修改,这个技巧尤其有用.

数组的维数不只一个,就是多维数组.
int matrix[2][3];

int matrix[6][10];
int *mp;
mp = &matrix[3][8];
? matrix 是6行10列还是 10行6列?
答案是两种解释都可以.
因为在内存中,数组元素的实际存储方式是确定的.

一维数组名的值是一个指针常量,它的类型是“指向元素类型的指针”,它指向数组的第一个元素.
多维数组名也类似, 它指向第一维的元素实际上是另一个数组.
int matrix[3][10];
可以看作是一个一维数组,包含3个元素,只是每个元素恰好是包含10个整型元素的数组.
matrix 这个名字的值是一个指向它第一个元素的指针,matrix是一个指向一个包含10个整型元素的数组的指针.

这个表达式实际上就是下标
( matrix + 1) 即 matrix[1]
( (matrix + 1) + 5) 即 ( matrix[1] + 5)
还可以再次用下标代替间接访问符
即 matrix[1][5]

**注意: 不能用都好分割来表示多维数组 例如 matrix[4, 3]; 它不是 4X3的矩阵,它只是一个含有3个元素的 一维数组,因为编译器会忽略逗号前的4;

下面的声明合法嘛?
int vector[10], vp = vector;
int matrix[3][10],
mp = matrix;
结论:第一个合法,第二个非法.
第一个,它为一个整型数组分配内存,并把vp声明为一个指向整型的指针,并把它初始化为指向vector数组的第一个元素.vector和vp具有相同的类型:指向整型的指针.
第二个,它正确的创建来matrix二维数组,并把mp声明为一个指向整型数组的指针.我们因该这样声明一个指向整型数组的指针,
int (p)[10];
这个声明看起来有点复杂,但是它事实上并不是很难.你只要假定它是一个表达式并对他求值.下标优先级高于间接访问,但由于括号的存在,首先执行的还是间接访问,所以
p是个指针,但它指向什么呢?接下来是下标引用,所以p指向某种类型的数组.这个声明表达式中没有更多的操作符,所以每个数组的每个元素都是整数.
所以第二个声明加初始化后是下面这个样子:
int (*p)[10] = matrix;
它使p指向matrix的第1行.
**但是不能这样声明: Int (*p)[] = matrix; 这样数组的长度不见了. **
有的编译器能捕捉到这样的错误,有的捕捉不到.

作为函数参数的多维数组名的传递方式和一维数组名相同--实际传递的是个指向数组第一个元素的指针.但是,两者之间的区别在于,多维数组的每个元素本身是另外要给数组,编译器需要知道它的维数,以便为函数形参的下标表达式进行求值.这里有两个理智,说明了他们之间的区别:
int vertor[10];
func1(vector):
参数vector的类型是指向整型的指针,所以 func1的原型可以是下面两种中的任何一种:
void func1(int *vec);
void func1(int vec[]);
作用于vec上面的指针运算把整型的长度作为它的调整因子.

对于矩阵
int matrix[3][10];
func2(matrix);
这里的参数matrix的类型是指向包含10个整型元素的数组的指针.func2的原型可以是下面两种形式中的任何一种
void func2( int (*mat)[10] );
void func2 (int mat[][10] );
mat的第一个下标根据包含10个元素的整型数组的长度进行调整,接着第二个下标根据整型的长度进行调整,这个原先的matrix数组一样.
这里的关键在于,编译器必须知道第2个以及以后各维的长度才能对各下标进行求值,因此在原型中必须声明这些维的长度.第1维的长度并不需要,因为计算下标值时用不到它.
注意:
把func2 写成下面是不正确的:
void func2(int **mat);
把mat声明为一个指向整型指针的指针,它和指向整型数组的指针并不是一回事.

对于多维数组,数组元素的存储顺序就变得非常重要.
一种是只给出一个常常的初始序列的值
int matrix[2][3] = {10, 11, 12, 13, 14, 15 };
第二种,基于多维数组实际上是福大元素的一维数组这个概念.
例如 声明

使用缩进是非必须的,但是这样做更加有利于阅读.

除了类型之外,指针变量和其他变量很相似.正如你可以创建整型数组一样,你也可以声明指针数组.
例如:
int api[10];
为了弄清楚这个复杂的声明,我们假定它是一个表达式,并对它进行求值.
下标优先级高于间接访问,所以在这个表达式中,首先执行下标引用.因此,api是某种类型的数组(它包含10个元素).在取得一个数组元素之后,随机执行的是间接访问操作.这个表达式不再有其他操作符,所以它的结果是一个整型.
对数组的某个元素执行间接访问操作后,我们得到一个整型值,所以api肯定是个数组,它的
元素类型是指向整型的指针.
关于运算符优先级:
运算符优先级.

什么地方会用到指针数组呢?
例子:

sizeof(keyword)是整个数组所占用的字节数.而sizeof(keyword[0])的结果则是每个元素所占的字节数.这两个值相除就是数组元素的个数.
这个数组可以用于计算一个C源文件中关键字个数的程序中.

思考
如果这样声明呢?

矩阵的存储方式看上去效率低一些,因为它的每一行的长度都被固定为刚好能容纳最长的关键字.但是它不需要任何指针.
另外,指针数组本身也要占用空间,但是每个字符串常量占据的内存空间只能是它本身的长度.

如果字字符集中字符串的长度都差不多,那么用矩阵的方式紧凑些,
如果字符集中字符串的长度千差万别,甚至有超长字符串,可以用指针数组.

人们时常选择指针数组方案,但是略微改动

最新文章
安卓获取不到gpu名字
目录GPU技术支持-业务篇-显示异常问题排查前言概述排查思路基本状态确认个例or共性问题验证措施-对换验证中间层状态判断验证措施显卡配置状态验证措施常见问题排查无显示问题(黑屏)确认系统状态判断显卡状态确认EDID状态、确认显示接口状
seo网站推广费用
SEO网站推广费用因多种因素而异,包括网站的规模、目标关键词的竞争程度、推广策略的选择等。SEO推广费用可以从几千元到数万元不等。具体而言,费用可能包括专业SEO团队的服务费、关键词优化费用、网站内容更新与维护费用等。选择合适的SEO
外卖一份面收入5块5:代运营治不了小餐饮的窘迫
  外卖代运营可能是伪商业模式。   王先生觉得,外卖平台并没有让生意变得好做一点。   2019年10月,他和家里人在深圳开了家主营粉面的快餐店。店铺还在装修的时候,美团外卖运营人员就找上门来谈合作,他接入了美团外卖。可只把店铺
共享汽车的使用费用如何计算?
共享汽车的使用费用计算方式挺多的。像一度,无需押金,按分钟和公里付费,2 块 1 公里,2 毛一分钟,结束后从信用卡扣钱。有车也是无需押金,1.5 元/公里加 0.15 元/分钟。驾呗同样无需押金,6 小时内 0.25 元/分钟,6 小时后 0.1 元/分钟
好视通云会议
  使用好视通云会议时大家听主会场发言,其他人都能听到,我听不到是怎么回事?  请您根据提示进行排查,请您在我们客户端主界面点击一下“音频”,然后请点击弹框里第一项“测试扬声器”,请您听一下,是否可以听到一段音乐声呢?  
排列五开奖结果第2021160期 一等奖中出53注
  今天是2021年06月19日,中国体育彩票排列五迎来了第2021160开奖时刻,小编昨天花了100块大洋买了直选大复式号,能否搏个1000万。我一直在想,如果中了1000万,怎么办?  彩种:体彩排列五(排列五)  期号:2021160期  开奖日期
香港特马资料免费大全赢钱买什么,关于香港特马资料免费大全赢钱买什么的问题,我必须首先指出,任何涉及赌博的行为都是违法的,并且存在极高的风险。赌博不仅可能导致财务损失,还可能对个人的心理、家庭和社会关系
摘要:关于香港特马资料免费大全赢钱买什么的问题,提醒广大市民,任何涉及赌博的行为都是违法的,存在巨大风险并可能导致严重后果。赌博不仅损害个人财务,更可能破坏心理、家庭和社会关系。强烈建议远离赌博,遵守法律法规,保护自身安全
数据结构实验四在线等价类排序输出
使用模拟指针实现本实验。输入一个1-9的正整数n,代表要创建n个元素,例如输入5,则代表创建一个1,2,3,4,5组成的元素表。再输入一个大于0正整数r,代表后面要输入r个等价关系。分行输入r个等价关系,格式如(
Python爬虫系列-获取每天黄金价格(编写爬虫的过程和编写代码思路详细解析)
        最近因为经济形势不好,黄金这样的硬通货价格持续走高,而且现在已经到了相当之高的程度。介于理财投资的低迷,黄金的长期投资说不定可以跑赢通胀。对于我们新手的投资,本着低买高卖的原则,总不会亏太多
【夜读】提升自己最好的方式
高度专注生活中,不管是哪个领域的高手,往往都是非常专注的人。做事总是东一榔头西一棒槌,或是频繁被琐事牵绊住心神,很难把一件事做好。把有限的精力放在重要的事情上,才有可能充分发挥自己的潜能。拥有专注力,是一个人走向优秀的开始
相关文章
推荐文章
发表评论
0评