c语言指针学习

#include <stdio.h>

  前言

  近期俄罗斯之陨星、四月份之血月、五月京底雪花以及天朝各种血腥和乱,给丁一如既往种未知的预感。佛祖说之末法时期,五浊恶世
,十恶之世,人更任由心法约束,道德沦丧,和现在正巧吻合。尤其是以天朝,空气,水,食品,你能够告诉还有没发出问题之吧?不知大难至,世人还忙。祸福相依,危中有机。那些高级生命,出于爱心,会救渡我们,但是你如果失去思维,去发现机缘。
最近于清闲,没事就学点基础知识,整天当达成层晃,感觉天旋地转的决心,接地气。关于指针我读的时节学了好几,我之教员说“指针很不便呢“,当时看这老师十分谦虚之。后来才懂其实他思念说”我呢将不理解”,不理解就变胡乱比喻的了,把指针比喻成门牌号,信封邮寄地址,现在我见到指针就想起门牌号,信封地址。想想都是泪水。

void main()

  地址

   说及指针,先说说地方,看无异段小序

#include "stdio.h"

int main()
{
    int a = 10;
    int *p = &a;
    printf("%p\n", p);
    return 0;  
}

// output
0x7fff8b6a378c

 

  每当自己看来指针的出口
像这种“0x7fff8b6a378c”天道,头都异常了,那时候老师就是地址,搞得糊里糊涂的。那什么是地方为?当然我拉你到一下。是网
RAM
中之一定岗位,通常因为十六进制的数字代表,系统经过这地址,就得找到呼应的内容。当使用80386时常,我们要区分以下三种不同的地址:逻辑地址、线性地址、物理地址;在开展C语言指针编程中,可以读取指针变量本身价值(&操作),实际上是价值就是是逻辑地址,它是对立于你眼前过程数据段的地址(偏移地址),不跟绝对物理地址相互关联,比如上面十分“0x7fff8b6a378c”
就是逻辑地址。逻辑地址不是叫一直送至内存总线,而是受送至内存管理单元(MMU)。MMU由一个或者雷同组芯片组成,其效力是管逻辑地址映射为大体地址,即开展地址转换。下面是变关系图。

图片 1

 

  关于内存地址怎么变可以参见一下之博文。《再遵照逻辑地址、线性地址》、
《我懂得的逻辑地址、线性地址、物理地址与虚拟地址》

{

  指针

  c语言相比汇编算应该算高档了,却保存的了操作地址被快速之以抽象的款式。那么指针到底是呀吧?
在那按照经典《c 程序设计语言》 是如此讲述 :
”指针是均等栽保存变量地址的变量“,指针是一个例外之变量,它里面储存的数值为解释成外存里的一个地点,指针与地点不要胡乱在并,指针是储存地点一个变量,地址是外存分配。指针可以针对这内存地址,也得以对任何一个内存地址,当指针指向一个内存地址,它们之间才发生关系,通过是指针去操作这块内存,所以指针把我们捎到地方层面去操作数据,在php,java
这些高级语言没有当即同样叠的操作。举个例子

//字符串翻转例子

#include “stdio.h”
#include “string.h”

void revstr(char *);

int main()
{
   char str[] = “Zhen Shan Ren is good!”;
   revstr(str);
   puts(str);
}

void revstr(char *str)
{
   char *start, *end, temp;
   start = str;
   end = start + strlen(str) -1;
   while (start++ < end–) {
       temp = *start;
       *start = *end;
       *end = temp;
   }
}

 

  上面的事例是于指针的角度去处理字符串,我再也revstr
函数中定义了一定量只指针,一个指南针指为字符串的首地址,另一个指南针指于字符串的末段地址,把内容互换。
指针提供这样方便,可以透过加、减来访问这同一片内存。然后还错过改变内存的价值。如果没指针,只能去操作这样逻辑地址 “0x7fff8b6a378c”夺计算下一个或者上一个逻辑地址,会无会见疯狂掉为?所以指针把我们捎到地方层面去操作数据。指针难点是我们不是杀理解有些复杂的数据类型的在内存中存储。指来指去不知底针对那了。如果您可知非常清楚内存的布,就非会见指错地方!


int a1=10;
int a2=11;
int * pa1, * pa2;
pa1 = &a1;
pa2 = &a2;

  指针的几乎独概念

   1.指针之类别

      基本数据类比如 int、char ,还有 一些犬牙交错的本 int
(*p)[], 指向数组的指针,像这种的判断即便是负针名字去掉
, 指针的花色类型就是 int(*)[],其实就算是凭于数组的指针

   2.指针所对的路

   
  当您通过指针来拜会指针所针对的内存区时,指针所针对的品类决定了编译器将将那片外存区里之始末作为什么来对待。
 你一味须将指针声明语句被的指针名字跟名字左边的指针声明符*失掉丢,剩下的就是是指针所指向的种。

     例如:int*ptr:指针所针对的路是int
  int(*ptr)[3]:指针所指向的的档次是int()[3] 

   3.指针的价

   
 我们说一个指南针的价是XX,就一定给说该指针指为了以XX为首地址的一律片内存区域;我们说一个指南针指于了某块内存区域,就相当给说该指针的价是这块内存区域的首地址。 

 看同样段代码:这段代码是问问你p1 是否以及p2 相等?

#include “stdio.h”

int main()
{
   char *p1,*p2,*p3;
   char ch[] = {‘a’, ‘b’, ‘c’};
   char **pp;
   p1 = ch;
   pp = &ch;
   p2 = *pp;
   
   if (p1 == p2) {
     printf(“p1  == p2\n”);
   } else {
     printf(“p1 != p2\n”);
   }

   printf(“p3 = %p”, p3);
   return 0;
}

 

  结果是:

//p1 != p2//p3 = 0x4005f0dxy

 

&ch  指针类型为 char (*)[3], 当运行到pp=&ch 时候,编译器会骂你
“warning: assignment from incompatible pointer type”
指针类型不配合(在vc6下蛋直报错)。看一下p3
会发出一个价值,未初始化指针是出内存地址的,而且是一个废品地址。不知底此内存地址指向的价值是什么。这就是干吗不用对未初始化指针取值的缘故。最好之事态是若收获到的凡污物地址接下你要对程序进行调试,最酷的情景则会促成程序崩溃。以后,每遇一个指针,都应有咨询:这个指针的种是什么?指针指的类是啊?该指针指为了何?  

再有一个题材可以试试

#include “stdio.h”

int main()
{
 int a[5] = {1,2,3,4,5};
 int *p = (int *)(&a+1);
 printf(“%d,%d”, *(a+1), *(p-1));
}

 

  答案在这个

printf(“a1=%d \pa1:%p\n”,a1,pa1);
printf(“a2=%d \pa2:%p\n”,a2,pa2);

  指针与反复组 

  “数组名就是恃针”,“你虽管作为指针理解”这是教工教的,却没被个成立之分解,就如有团伙教育无神论一样,你若信神就是信,我说这便是凶恶,缺乏对人口无比起码的倚重,当然在某某团伙的眼里我们都是奴才。好吧,假设数组名是指针

#include “stdio.h”

int main()
{
int a[] = {1,2,3,5};
int *p = a;
printf(“a = %d, p =%d”, sizeof(a), sizeof(p));
}
//output
//a= 16,p=4

 

  从出口结果看两者根本就是两单东西,只能说数组名神似指针,数组名的内涵在于其代表实体是平等栽多少结构,这种数量结构就是数组;那么累组名到底是啊:

  符号表是编译原理中的一个定义,应用叫编译器的词法分析与语义分析两独号。词法分析的对象是为编译器能明了就是单数组就吓了,那么语义分析阶段就用确定此数组的现实性空间了。所以我们定义了一个屡屡组,编译器就会在符号表中加入数组的名字a,并且根据那指定的深浅,开辟一段落内存空间,把当时段内存空间的首地址(也尽管是首先单因素的地址)存入符号表,这为即是怎么我们透过数组名就得错过做客数组的因素了。编译器这么做是为了使我们采取数组更加的惠及,易懂。也有人说a是一个内存地址,也没有啊不妥的,因为编译器允许我们直接把a作为数组首地址来之所以。数组是如出一辙种线性的数据结构,数组名指向了那无异切片内存。

 –EOF–

当初学者难免产生错,欢迎推荐指正:-D

补充:

        
本来是学之总,没想到会被博客园编辑推荐,顿时觉得脱单了受大家围观一样,除了前言其他还是一般般,能力实际少。见笑与大方之家。

         不思给garbageMan 踢爆,当然吃他踹爆人很多,一main到底的谭先生也未能幸免。

        
感谢garbageMan大神的指和批评(鞠躬!),以后多努力,写有质量更高博文,谢谢各位!


*pa1=*pa2;

printf(“赋值后\n”);

printf(“a1=%d\ pa1:%p\n”,a1, pa1);
printf(“a2=%d\ pa2:%p\n”,a2, pa2);

//*pa1=*pa2暨a1=a2操作相同

//

pa2=pa1;//把pa1底指针地址复制给了pa2
printf(“a1=%d\ pa1:%p\n”,a1, pa1);
printf(“a2=%d\ pa2:%p\n”,a2, pa2);
//指针地址复制,把pa1底指针地址复制给了pa2继如今指针pa1跟pa2还针对变量
a1

return 0;
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图