日韩在线免费播放-日韩在线免费av-日韩在线免费-日韩在线毛片-国产高清不卡视频-国产高清不卡

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > C語言指針

C語言指針 時間:2018-12-25      來源:華清遠見

關于指針我上學的時候學,我的老師說“指針很難呢“,把指針比喻成門牌號,信封郵寄地址,現在我看到指針就想起門牌號,信封地址。

地址:

說到指針,先說說地址,看一段小程序

#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由一個或一組芯片組成,其功能是把邏輯地址映射為物理地址,即進行地址轉換。下面是轉換關系圖。

C語言指針,C語言學習

指針:

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”去計算下一個或上一個邏輯地址,會不會瘋掉呢?所以指針把我們帶入到地址層面去操作數據。指針難點是我們不是很清楚有些復雜的數據類型的在內存中存儲。指來指去不知道指向那了。如果你能很清楚內存的分布,就不會指錯地方!

指針的幾個概念:

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));

}

 

答案在此

指針與數組 

“數組名就是指針”,“你就把當做指針理解”,假設數組名是指針

#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作為數組首地址來用。數組是一種線性的數據結構,數組名指向了那一片內存。

上一篇:嵌入式學科:float

下一篇:干貨分享 javasleep

熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部

主站蜘蛛池模板: 青山知可子冲绳草莽英雄1969| 膨腹爱好者撑肚子视频| 凌晨晚餐| 基础设施建设产业市场| 快播王欣| 富贵不能淫翻译| 派拉蒙影业| 错爱电影| 陈宝莲徐锦江夜半2普通话| 来5566看av激情电影使劲撸| 龙八夷| 快手快枪快手演员表| 一句话让老公下面硬| 刑道荣| 宋恩彩为艺术奉献的作品有哪些| 生死劫电影| 羽毛球队名诙谐有趣的名字| www.56.com| 抓特务电视剧大全播放| 林采薇| 暴雪电影| 五年级字谜| 甜蜜高潮 第一季 电视剧| 江南好简谱| 免费看网站| 多田有花与老丈人电影叫什么名字| 春心荡漾在线观看| 性视频动态图| 栏目大全| 潜龙轰天 电影| 男女视频在线播放| 爱自由| 掐脖子的视频| 任港秀| 远景山谷 (1981)| 2024年12月四级作文| 无耻之徒豆瓣| 亚纱美| 小飞鱼| 杨贵妃黄色片| 3d性欧美动漫精品xxx游戏|