指针

本节探讨c语言中最重要的指针,c语言之所以如此灵活,关键就在于指针的运用,这是一个难点,也是学c语言必须要掌握的内容。

1、什么是指针?

指针如其名字所示的一样,他是一种有方向性的数据,能够指向别的数据类型。首先要明白的一点是,指针也是一种数据。那么在c语言中的指针是怎么运作的呢?在c语言中,我们通过*来创建指针数据,我们通过一个例子来看:

int a = 12; // 创建整形变量 a  
int *p = &a; // 创建指针 p 指向 a  
printf("a的地址:%p  a的大小为:%lu Byte  a的内容:%d\n", &a, sizeof(a), a); // 输出 a 的地址、大小及存储内容  
printf("p的地址:%p  p的大小为:%lu Byte  p的内容:%p\n", &p, sizeof(p), p); // 输出 p 的地址、大小及存储内容  
printf("p指向的内容为 %d\n", *p); // 输出p指向的内容 

在该例子中,我们创建了一个变量 a=12,然后创建了一个指针 p 指向 变量 a,我们看看程序输出情况:

a的地址:0x7fff5fbff8d8  a的大小为:4 Byte  a的内容:12  
p的地址:0x7fff5fbff8d0  p的大小为:8 Byte  p的内容:0x7fff5fbff8d8  
p指向的内容为 12 

从输出结果可以看出,变量 a 占用内存单元的4个字节,存储的是数值 12,指针 p 占用内存单元的8个字节,存储的是一个地址数据,进一步观察可以发现,p对应内存单元所存储的地址数据和变量a的地址一致,这样我们就可以通过 p 直接访问 a 的内容,换句话说,p 就是 a。验证如下:

*p=13;  
printf("a = %d\n", a); // 输出 a 的内容 

前面的代码中我们给变量 a 赋值 12,在该代码中,我们没有直接对 a进行操作,我们看看结果又会怎样:

a = 13  

可以发现,我们通过指针 p 就可以间接修改 变量 a 的内容。

2、思考

通过上面的例子发现,我们可以通过指针绕过变量本身,直接修改变量的值,换句话说,我们可以通过指针直接操作变量对应的地址单元!这就是指针的本质。那么,为什么要这样做呢?
a、我们知道,数据在内存中的存储都是以基本的内存单元按顺序进行排列的,对变量的操作其本质就是操作变量对应的地址单元,我们每创建一个变量,实际上就是用一个标识符(变量名)标识了一块内存单元,这样当创建大量的变量时就会产生大量的标识符,这是不利于变量的调用的。当对大量的数据或者具有某种结构和顺序的数据进行操作时,指针的优势就凸现出来,因为指针是直接通过地址单元来操作变量的,而我们对地址单元的简单运算,就能在大量不同的变量之间跳转,非常的灵活。
b、当然这也产生了一些问题。由于指针是对地址单元的直接操作,而如果我们错误的将指针定位到不该指向的内容时,有时会导致整个程序的崩溃,这一点一定要注意。

3、特殊的指针

a、数组
c语言中数组本身就是一种指针,只不过写法略有不同。

int ar[]={1,2,3};  
int *arp=ar;//int *arp={1,2,3};这样是错误的  
  
//输出数组的值  
printf("%d\n", arp[0]);   // *arp  
printf("%d\n", arp[1]);   // *arp+1  
printf("%d\n", arp[2]);   // *arp+2  
  
printf("ar的地址:  %p\narp的地址: %p \n", &ar, &arp);  

输出结果:

1  
2  
3  
ar的地址:  0x7fff5fbff8c8  
arp的地址: 0x7fff5fbff8c0 

在上面的例子中,我们将一个指针指向了数组,有没注意到数组名的前面没有加 &地址操作符?这是因为数组名本身就是一个指针!这两个指针占用不同的内存单元,但是他们都能对数组进行操作。
b、字符串
前面有提到,字符串本身就是一种数组,那同样的,他也可以用指针来表示:

char *str = "This is a string!";  
printf("%s\n", str); 

输出:

This is a string!  

c、指针数组
在数组名的前面加 * 就成为了指针数组:

//创建指针常量数组  
char *name[]=  {  
    "Jack",  
    "Tom",  
    "Helen",  
    "April",  
};  
// 输出  
for (int i=0; i<4; i++) {  
    printf(" %s\n",name[i]);  
} 

输出结果:

Jack  
Tom  
Helen  
April 

d、指针函数
函数本身也是一种指针(函数的细节将在别的章节讨论),我们当然也可以通过指针指向函数:

//(*p)为固定写法,表示该指针指向函数  
void (*p)(char);  
p=func;  
  
// 测试函数和指针指向的地址  
printf("func地址: %p\n", &func);  
printf("p指向地址: %p\n", p);  
  
// 指针调用函数  
(*p)('A'); // 可以简化为p('A')  

输出结果:

func地址: 0x100000e80  
p指向地址: 0x100000e80  
func()函数被调用,传入字符参数 A 

可以发现这两个地址完全一致。

4、其他

在计算机领域流传一句话:多一层间接,没有解决不了的问题。指针是c语言构建简洁结构的关键,在以c语言为基础的面向对象设计语言中,这种对指针的运用将显得格外突出和复杂。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,009评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,808评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,891评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,283评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,285评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,409评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,809评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,487评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,680评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,499评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,548评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,268评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,815评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,872评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,102评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,683评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,253评论 2 341

推荐阅读更多精彩内容

  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,421评论 3 44
  • void* 类型指针:通用变体类型指针;可以不经转换,赋给其他指针,函数指针除外;malloc返回的就是void*...
    冰吉凌阅读 3,304评论 0 18
  • 指针 指针是什么 为了了解指针的概念,我们先来看一个小故事。话说福尔摩斯派华生到威尔爵士居住的城堡去取回一个重要的...
    去留无意hmy阅读 543评论 0 1
  • C语言指针的总结 1. 变量 不同类型的变量在内存中占据不同的字节空间。 内存中存储数据的最小基本单位是字节,每一...
    xx_cc阅读 3,678评论 11 39
  • 那年,花开无声。 清晰的记得,15年10月份,我们在这里相遇,并有了交集。 我们的故事… 将近两年,太多的趣事发生...
    沙坡特阅读 636评论 2 5