怎么能查到一个人的位置,手机关机能查到位置吗

posts - 22,&
comments - 7,&
trackbacks - 0
深入理解const char*p,char const*p,char *const p,const char **p,char const**p,char *const*p,char**const p
一、可能的组合:
(1)const char*p
(2)char const*p
(3)char *const p(4)const char **p
(5)char const**p
(6)char *const *p
(7)char **const p
当然还有在(5)、(6)、(7)中再插入一个const的若干情况,不过分析了以上7中,其他的就可类推了!
二、理解助记法宝:
1。关键看const 修饰谁。
2。由于没有 const *的运算,若出现 const * 的形式,则const实际上是修饰前面的。
比如:char const*p,由于没有const*运算,则const实际上是修饰前面的char,因此char const*p等价于const char*p。也就是说上面7种情况中,(1)和(2)等价。 同理,(4)和(5)等价。在(6)中,由于没有const*运算,const实际上修饰的是前面的char*,但不能在定义时转换写成 const(char *)*p,因为在定义是"()"是表示函数。
三、深入理解7种组合
(0)程序 在执行时为其开辟的空间皆在内存(RAM)中,而RAM里的内存单元是可读可写 的;指针只是用来指定或定位要操作的数据的工具,只是用来读写RAM里内存单元的工作指针 。若对指针不加任何限定,程序中一个指针可以指向RAM中的任意位置(除了系统敏感区,如操作系统内核所在区域)并对其指向的内存单元进行读和写操作(由RAM的可读可写属性决定);RAM里内存单元的可读可写属性不会因为对工作指针的限定而变化(见下面的第4点),而所有对指针的各种const限定说白了只是对该指针 的 读写权限 (包括读写位置)进行了限定 。
(1)char *p:p是一个工作指针,可以用来对任意位置 (非系统敏感区域)进 行读操作和写操作 ,一次读写一个字节(char占一个字节)。(2)const char*p或者char const *p(因为没有const*p运算,因此const修饰的还是前面的char):可以对任意位置(非系统敏感区域)进行&只读& 操作。(&只读&是相对于char *p来说所限定的内容)(3)char *const p(const 修饰的是p):只能对&某个固定的位置& 进 行读写操作,并且在定义p时就必须初始化(因为在后面不能执行&p=..&的操作,因此就不能在后面初始化,因此只能在定义时初始化)。(&某个固定的位 置&是相对于char *p来说所限定的内容)可以总结以上3点为:char *p中的指针p通常是&万能&的工作指针 ,而(2)和(3)只是在(1)的基础上加了些特定的限制 ,这些限制在程序中并不是必须的,只是为了防止程序员的粗心大意而产生事与愿违的错 误。另外,要明白&每块内存空间都可有名字;每块内存空间内容皆可变(除非有所限) & 。比如函数里定义的char s[]="hello";事实上在进程的栈内存里开辟了6个变量共6个字节的空间,其中6个字符变量的名字分别为:s1[0]、s1[1]、 s1[2]、s1[3]、s1[4]、s1[5](内容是'\0')
待验证 : 还有一个4字节的指针变量s 。不过s是&有所限制&的,属于char *const类型,也就是前面说的 (3)这种情况,s一直指向s[0], 即(*s==s[0]=='h'),可以通过*s='k'来改变s所指向的 s[0]的值,但不能执行(char *h=&aaa&;s=h;)来对s另外赋值。
(4)上面的(2)和(3)只是对p进行限定,没有也不能对p所指向的空间进行限定,对于"char s[]="hello";const char*p=s;" 虽然不能通过*(p+i)='x'或者p[i]='x'来修改数组元素s[0]~s[4]的值,但可以通过*(s+i)='x'或者s[i]='x'来修改原数组元素的值--RAM里内存单元的可读可写属性不因对工作指针的限定而改变,而只会因对其本身的限定而改变。如const char c=&A&,c是RAM里一个内存单元(8字节)的名字,该内存单元的内容只可读,不可写。
(5)const char **p或者char const**p :涉及两个指针p和 *p。由于const修饰char ,对指针p没有任何限定,对指针*p进行了上面情况(2)的限定。
(6)char *const *p:涉及两个指针p和 *p。由于const修饰前面的char*,也就是对p所指向的内容*p进行了限定(也属于前面的情况(2))。而对*p来说,由于不能通过"*p=..."来进行另外赋值,因此属于前面的情况(3)的限定。
(7)char **const p : 涉及两个指针p和 *p,const修饰p,对p进行上面情况(3)的限定,而对*p,没有任何限定。
四、关于char **p 、const char **p的类型相容性问题
char *p1;const *p2=p1;//合法
char **p1;const char**p2=p1;//不合法,会有警告warning: initialization from incompatible pointer type
char **p1;char const**p2=p1;//不合法,会有警告warning: initialization from incompatible pointer type
char**p1;char*const*p2=p1;//合法
2。判断规则
明确const修饰的对象!对于指针p1,和p2,若要使得p2=p1成立,则可读做 :
&p1是指向X类型的指针,p2是指向&带有const限定&的X类型的指针 &。 只要二者的X类型一样,就是合法的。
char *p1;const *p2=p1;//合法:p1是指向(char)类型的指针,p2是指向&带有const限定"的(char)类型的指针。
char **p1;const char**p2=p1;//不合法:p1是指向(char*)类型的指针,p2是指向 ((const char)*)类型的指针。
char **p1;char const**p2=p1;//不合法;与上等价。
char**p1;char*const*p2=p1;//合法: p1是指向(char *)类型的指针,p2是指向&带有const限定"的(char*)类型的指针。
1。 含有const的单层或双层指针的统一读法:
&p是一个指针,是一个[&带有const限定&的]指向[&带有const限定&的]X类型的指针&。
l例如:const char* const *p就是说:p是一个带有const限定的指向带有const限定的(char*)类型的指针。
2。定义时const修饰的对象是确定的,但不能在定义时加括号,不然就和定义时用&()&表示的函数类型相混淆了!因此定义时不能写(char *)const *p或者(const char) **p。
六、问题探讨(由于博文后的留言有字符数目限制,将回复移到这里)
问题1 (见博文后留言):讲解非常好,不过有个问题想探讨下: 例如: const char wang[]={"wang"}; char *p; p= 是错误的。 所以char *p中的P不能指向常变量。 (1)需要补充纠正。
回复 : 你好!谢谢指正!我在ubuntu 10.04(gcc 4.4.3)下做了如下测试: //test_const.c#include&stdio.h&int main(){const char wang[]={"wang"};char *p;p=p[2]='c';printf("p is %s\n",p);return 0;}编译 :
gcc -o test_const test_const.c输出如下 :test_const.c: In function &main&:test_const.c:17: warning: assignment discards qualifiers from pointer target type执行:
./test_constp is wacg结论: 根据本博文中第四点--相容性问题,将const型的wang赋值给p是不合法的。但编译器对其的处理只是警告,因此执行时通过p修改了只读区域的数据。这应该是该编译器处理不严所致后果,不知你用的什么编译器?
问题2 回答
提到的问题
// test.cint main() {const char* s1 = "test";char *s2 = s1;s2 = "It's modified!";printf("%s\n",s1);}out: It's modified!;这样也可以吗? 照我的理解岂不是const限定符在c语言里只是摆设一个?
(1)首先,以上代码编译时会出错warning: initialization discards qualifiers from pointer target type,
因为char *s2 = s1和问题1提到的一样,不符合相容规则。
(2)输出结果是正确的,代码分析如下:
int main() {const char* s1 = "test"; // 在只读数据区(objdump -h test后的.rodata区)开辟5字节存储"test",并用s1指向首字符&t&。 char *s2 = s1; // s2也指向只读数据区中&test&的首字符't'。 s2 = "It's modified!"; // 在只读数据区开辟15字节存储"It's modified!",并将s2由指向't'转而指向"It's modified!"的首字符'I'。 printf("%s\n",s1); // 从s1所指的&t&开始输出字符串"test"。 }
(3)总结:提问者的误区在于,误以为s2 = "It's modified!"是对&test&所在区域的重新赋值,其实这里只是将&万能&工作指针s2指向另外一个新开辟的区域而已。比如若在char *s2 = s1后再执行s2[2]='a'则是对&test&的区域进行了写操作,执行时会出现段错误。但这个段错误其实与const没有关系,因为&test&这块区域本身就是只读的。为了防止理解出错,凡事对于对指针的赋值(比如 s2 = "It's modified!" ),则将其读做:将s2指向& It's modified! &所在区域的首字符。
(4)额外收获:执行gcc -o test test.c后,&test&、&It's modified!&、"%s\n"都被作为字符串常量存储在二进制文件test的只读区
域 (.rodata)。事实上,一个程序从编译到运行,对变量空间分配的情况如下:
A。赋值了的全局变量或static变量=&放在可执行文件的.data段。
B。未赋值的全局变量或static变量=&放在可执行文件的.bss段。
C。代码中出现的字符串常量或加了const的A=&放在可执行文件的.rodata段。
D。一般的局部变量=&在可执行文件中不占空间,在该二进制文件作为进程在内存中运行时才为它分配栈空间。
E。代码中malloc或new出的变量=&在可执行文件中不占空间,在该二进制文件作为进程在内存中运行时才为它分配堆空间。
问题3:(待进一步分析) 验证博文中 三(3)提到的是否为s分配空间,初步分析结果为:不分配!文中的s只是s[0]的地址的代号而已。
#include&stdio.h&int main() {int a=3;char s1[] = "test";int b=4;char s2[] ="test2";printf("the address of a is %u\n",&a);printf("s1 is %u\n",s1);printf("the address of s1 is %u\n",&s1);printf("the address of b is %u\n",&b);printf("s2 is %u\n",s2);printf("the address of s2 is %u\n",&s2);}
输出结果:
the address of a is s1 is the address of s1 is the address of b is s2 is the address of s2 is
由结果可以看出,编译器做了些优化。
七、其他相关经典文章转载
王海宁,华清远见嵌入式学院讲师,对const关键字的理解
目前在进行C语言补习时,发现很多的同学对于const这个关键字的理解存在很大的误解。现在总结下对这个关键字理解上的误区,希望在以后的编程中,能够灵活使用const这个关键字。
1、 const修饰的变量是常量还是变量
对于这个问题,很多同学认为const修饰的变量是不能改变,结果就误认为该变量变成了常量。那么对于const修饰的变量该如何理解那?
下面我们来看一个例子:
int main{char buf[4];const int a = 0;
这个比较容易理解,编译器直接报错,原因在于&a = 10;&这句话,对const修饰的变量,后面进行赋值操作。这好像说明了const修饰的变量是不能被修改的,那究竟是不是那,那么下面我们把这个例子修改下:
int main{char buf[4];const int a = 0;
buf[4] = 97;printf(&the a is %d\n&,a);}
其中最后一句printf的目的是看下变量a的值是否改变,根据const的理解,如果const修饰的是变量是不能被修改的话,那么a的值一定不会改变,肯定还是0。但是在实际运行的结果中,我们发现a的值已经变为97了。这说明const修饰的变量a,已经被我们程序修改了。
那综合这两个例子,我们来分析下,对于第二例子,修改的原因是buf[4]的赋值操作,我们知道buf[4]这个变量已经造成了buf这个数组变量的越界访问。buf数组的成员本身只有0,1,2,3,那么buf[4]访问的是谁那,根据局部变量的地址分配,可以知道buf[4]的地址和int a的地址是一样,那么buf[4]实际上就是访问了const int a;那么对buf[4]的修改,自然也修改了const int a的空间,这也是为什么我们在最后打印a的值的时候看到了97这个结果。
那么我们现在可以知道了,const修饰的变量是不具备不允许修改的特性的,那么对于第一个例子的现象我们又如何解释那。
第一个例子,错误是在程序编译的时候给出的,注意这里,这个时候并没有生成可执行文件,说明const修饰的变量可否修改是由编译器来帮我们保护了。而第二个例子里,变量的修改是在可执行程序执行的时候修改的,说明a还是一个变量。
综上所述,我们可以得出一个结论,那就是const修饰的变量,其实质是告诉程序员或编译器该变量为只读,如果程序员在程序中显示的修改一个只读变量,编译器会毫不留情的给出一个error。而对于由于像数组溢出,隐式修改等程序不规范书写造成的运行过程中的修改,编译器是无能为力的,也说明const修饰的变量仍然是具备变量属性的。
2、 被const修饰的变量,会被操作系统保护,防止修改
如果对于第一个问题,有了理解的话,那么这个问题,就非常容易知道答案了。Const修饰的变量是不会被操作系统保护的。
其原因是操作系统只保护常量,而不会保护变量的读写。那么什么是常量?比如&hello world&这个字符串就是被称为字符串常量。
对于这个问题的另一种证明方法,可以看下面这个程序:
int main{char *buf = &hello world&;
printf(&the &a is %p, the buf is %p\n&,&a, buf);}
可以发现buf保存的地址是在0x这个地址附近的,而a的地址是在0xbf000000这个地址附近的,而0x附近的地址在我们linux操作系统上是代码段。这也说明了常量和变量是存放在不同区域的,自然操作系统是会保护常量的。
如果我们知道这个道理后,再看下面的题目:
int main{char *buf = &hello&;
buf[0] = &a&;printf(&the buf is %s\n&,buf);}
我们可以思考下,这个程序的运行结果会是什么呢?
答案是:报错error :在0x处不可以写。也就是说os保护常量的的区域,只能读不能写。
阅读(...) 评论()c++的问题int sz[2][3][4];int *psz=sz[0][0];for(i&2;i++)for(j&3;j++)for(k&4;k++)*(psz+3*4*i+4*j+k)中的3和4是什么意思-中国学网-中国IT综合门户网站-提供健康,养生,留学,移民,创业,汽车等信息
> 信息中心 >
c++的问题int sz[2][3][4];int *psz=sz[0][0];for(i&2;i++)for(j&3;j++)for(k&4;k++)*(psz+3*4*i+4*j+k)中的3和4是什么意思
来源:互联网 发表时间: 17:58:15 责任编辑:王亮字体:
为了帮助网友解决“c++的问题int sz[2][3][4];int *psz=sz[0][0];for(i&2;i++)for(j&3;j++)for(k&4;k++)*(psz+3*4*i+4*j+k)中的3和4是什么意思”相关的问题,中国学网通过互联网对“c++的问题int sz[2][3][4];int *psz=sz[0][0];for(i&2;i++)for(j&3;j++)for(k&4;k++)*(psz+3*4*i+4*j+k)中的3和4是什么意思”相关的解决方案进行了整理,用户详细问题包括:RT,我想知道:c++的问题int sz[2][3][4];int *psz=sz[0][0];for(i&2;i++)for(j&3;j++)for(k&4;k++)*(psz+3*4*i+4*j+k)中的3和4是什么意思,具体解决方案如下:解决方案1: psz是一个整数的指针=sz[0][0],就是psz指向数组第一个元素sz[0][0][0]的地址,psz+3*4*i+4*j+k就是指针psz后面的第3*4*i+4*j+k个整型地址,就是元素&sz[i][j][k]的地址,*(psz+3*4*i+4*j+k)就是取这个地址的值,也就是元素sz[i][j][k]。i,j,k分别代表数组的第1,2,3维,这样i,j,k分别从0开始到1,2,3循环一遍,输出数组的所有元素。i*3*4意思是第一维的第i行乘以第二维的长度3乘以第三维的长度4,得出第i行之前有多少个元素。可自己画图看解决方案2: 乘法运算 追问: 能详细点吗 回答: *(psz+3*4*i+4*j+k)你是问这句吗?还是全部? 追问: 就是这句 &可以怎么理解 回答: psz加(3乘以4乘以 i)加 (4乘以j) 加k别忘记了运算符优先 追问: 你确定这个不是指针指向的多维数组的地址,*这个你确定是乘????????如果是能所说的乘法运算那他是怎么把sz【2】【3】【4】输出一遍的
5个回答3个回答2个回答4个回答6个回答4个回答1个回答2个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答
相关文章:
<a href="/cse/search?q=<inputclass="s-btn"type="submit"text="<inputclass="s-btn"type="submit"text="<buttonhidefocusclass="s-btnjs-ask-btn"text="我要提问
<a href="/cse/search?q=

我要回帖

更多关于 怎么查一个人的位置 的文章

 

随机推荐