77百科网
当前位置: 首页 生活百科

c语言指针用法大全(C语言基础知识最核心的)

时间:2023-05-29 作者: 小编 阅读量: 3 栏目名: 生活百科

指针与const结合涉及常量指针与指针常量。指针与函数结合涉及函数指针与指针函数,同时也会涉及回调函数。如果变量是静态的,它会被初始化为0,;如果变量是自动地,它根本不会被初始化。如果试图通过指针修改这个字符串的值,程序就会出现未定义的行为。两个指针相减的结果是两个指针之间的元素个数。所以这个指针每加一步的步长就是数组的长度。由于它每跨一步都是整个数组,所以又称行数组。pa中存的也是这个地址。

指针是C语言最重要也是最难理解的部分,它在我们平时的工作中无处不在。

有人说学会了指针,C语言也就学会一半。为什么说指针难。因为指针与数组相结合就涉及数组指针与指针数组。指针与结构体结合就涉及结构体指针。指针与字符结合涉及字符指针。指针与const结合涉及常量指针与指针常量。指针与函数结合涉及函数指针与指针函数,同时也会涉及回调函数。指针和指针结合涉及到二维指针。

作者曾经因为上面的这些问题,困扰了许久。因而在网上找了许多的博客来解答疑惑。这篇文章,我试图将上面的知识点以例子的方式呈现给大家,我相信通过阅读本文,大家会对指针有更深一步的了解。文中涉及的例子均来源于网上。

1 指针的定义

我们知道,普通的变量存储的是一个值。而指针变量,它存储的也是一个值,只是这是一个特殊的值:它的值是另一个变量的地址

指针的定义形式如下:

datatype *name;或 datatype *name = value;

其意思就是name是一个指针,它指向的是一个类型为dataype的地址。

指针存储的是一个地址,如果需要获取这个地址对应的内容,可以通过解引用符*获取:

int a = 12;int *pa = &a;printf("*pa:%u.", *pa); // 输出是12;*pa = 14; // 此时a的值为14了

这里需要注意的一点,也是我以前经常迷惑的一点:定义指针时,编译器并不为指针所指向的对象分配空间,它只是分配指针本身的空间,除非在定义时同时赋给一个字符串常量进行初始化。比如:

int *a;...*a = 12;

上面这个代码段说明了一个极为常见的错误:我们声明了这个变量,但从未对它进行初始化,所以没法预测12这个值将存储于什么地方。如果变量是静态的,它会被初始化为0,;如果变量是自动地,它根本不会被初始化。无论哪种情况,声明一个指向整型的指针都不会"创建"用于存储整型值的内存空间。

但是, 下面的定义创建了一个字符串常量(为其分配了内存):

char *p = "breadfruit";

始化指针时所创建的字符串常量被定义为只读。如果试图通过指针修改这个字符串的值,程序就会出现未定义的行为。

除了上述的定义是对的外,其他的定义都是错误的:

float *pip = 3.14; // 错误!无法通过编译

2 指针的运算

指针(-) 整数指针存储的是一个地址,这个地址本质上是一个整数,所以可以加上或减去一个整数。但是它不是普通的加法或减法,指针加上或减去一个整数结果是另一个指针。但是,运算后的指针指向哪里呢?当一个指针和一个整数执行算术运算时,整数在执行加法(减法)运算前会根据合适的大小进行调整。这个"合适的大小"就是指针所指向类型的大小,"调整"就是把整数值和"合适的大小"相乘。

#include <stdio.h>int main(){int a = 10;int *pa = &a;double b = 99.9;double *pb = &b;char c = '@';char *pc = &c;printf("sizeof(int)= %u, sizeof(double)=%u, sizeof(char)=%u\n",sizeof(int), sizeof(double), sizeof(char));//最初的值printf("&a=%p, &b=%p, &c=%p\n", &a, &b, &c);printf("pa=%p, pb=%p, pc=%p\n", pa, pb, pc);//加法运算pa; pb; pc;printf("pa=%p, pb=%p, pc=%p\n", pa, pb, pc);//减法运算pa -= 2; pb -= 2; pc -= 2;printf("pa=%p, pb=%p, pc=%p\n", pa, pb, pc);return 0;}

运算结果:

sizeof(int)= 4, sizeof(double)=8, sizeof(char)=1&a=000000000061FE04, &b=000000000061FDF8, &c=000000000061FDF7pa=000000000061FE04, pb=000000000061FDF8, pc=000000000061FDF7pa=000000000061FE08, pb=000000000061FE00, pc=000000000061FDF8pa=000000000061FE00, pb=000000000061FDF0, pc=000000000061FDF6

由上面的结果可以看到,当对指针pa,pb,pc进行加1时,实际地址增加的是对应类型的大小。减法也一样。

指针 - 指针

只有当两个指针都指向同一个数组中的元素时,才允许从一个指针减去另一个指针。两个指针相减的结果是两个指针之间的元素个数。比如,如果p1指向array[i]而p2指向array[j],那么p2-p1的值就是j-i的值。如果两个指针所指向的不是同一个数组中的元素,那么它们之间相减的结果是未定义的,也是毫无意义的。

3 指针与数组3.1 数组指针(指向数组的指针)

数组指针,它是一个指针,指向的是一个数组。即它存的是一个数组变量的地址。所以这个指针每加一步的步长就是数组的长度。由于它每跨一步都是整个数组,所以又称行数组。

#include <stdio.h>int main(){int a[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};int (*pa)[4];pa = a;printf("a:%p, &a:%p, &a[0][0]:%p\n", a, &a, &a[0][0]);printf("pa:%p, (*pa)[0]:%u\n", pa, (*pa)[0]);pa;printf("&a[1]:%p, &a[1][0]:%p\n", &a[1], &a[1][0]);printf("pa:%p, (*pa)[0]:%u\n", pa, (*pa)[0]);return 0;}

运行结果:

a:000000000061FDE0, &a:000000000061FDE0, &a[0][0]:000000000061FDE0pa:000000000061FDE0, (*pa)[0]:1&a[1]:000000000061FDF0, &a[1][0]:000000000061FDF0pa:000000000061FDF0, (*pa)[0]:5

首先,pa是一个数组指针,它首先存的是数组a的首元素的地址,由于数组名也是数组的首地址,所以a, &a, &a[0][0]的地址相同。pa中存的也是这个地址。然后对pa进行解引用,*pa之后得到这个数组,然后(*pa)[i]就是获得这个数组下标为i的元素。

3.2 指针数组

指针数组,它本质上是一个数组,只不过整个数组存的类型是一个指针而已。

#include<stdio.h> int main(void){char *p1 = "Himanshu";char *p2 = "Arora";char *p3 = "India";char *arr[3];arr[0] = p1;arr[1] = p2;arr[2] = p3;printf("\n p1 = [%s] \n",p1);printf("\n p2 = [%s] \n",p2);printf("\n p3 = [%s] \n",p3);printf("\n arr[0] = [%s] \n",arr[0]);printf("\n arr[1] = [%s] \n",arr[1]);printf("\n arr[2] = [%s] \n",arr[2]);return 0;}

运行结果:

p1 = [Himanshu]p2 = [Arora]p3 = [India]arr[0] = [Himanshu]arr[1] = [Arora]arr[2] = [India]

4 指针与字符

在C语言中,表示字符串一般有两种形式,一种是数组的形式,一种是字符指针的形式。

数组形式:

char arr[] = "hello,world";

字符指针形式:

char *str = "hello,world";

虽然上面两种形式都能表示字符串,但是它们还是有些区别的:

存储方式字符数组由若干元素组成,每个元素存放一个字符,而字符指针变量只存放字符串的首地址,不是整个字符串。

存储位置。数组是在内存中开辟了一段空间存放字符串, 是存在栈区。而字符指针是在字面值常量区开辟了一段空间存放字符串,将字符串的首地址付给指针变量str。

赋值方式。对于数组,下面的赋值方式是错误的:

char str[10];str="hello"; // 错误!

而对字符指针变量,可以采用下面方法赋值:

char *a;a = "hello";

可否被修改。指针变量指向的字符串内容不能被修改,但指针变量的值(即存放的地址或者指向)是可以被修改的。

来源:稀土掘金,作者:Elec


对啦对啦!另外的话为了帮助大家,轻松,高效学习C语言/C,我给大家分享我收集的资源,从最零基础开始的教程到C语言项目案例,帮助大家在学习C语言的道路上披荆斩棘!可以来我粉丝群领取哦~

编程学习书籍分享:

编程学习视频分享:

整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)最重要的是你可以在群里面交流提问编程问题哦!

对于C/C感兴趣可以关注小编在后台私信我:【编程交流】一起来学习哦!可以领取一些C/C的项目学习视频资料哦!已经设置好了关键词自动回复,自动领取就好了!

    推荐阅读
  • 哈利波特第二部叫什么(哈利波特第二部的内容简介)

    哈利波特第二部叫什么《哈利·波特》第二部:《哈利·波特与密室》。小精灵多比劝诫并用一切手段阻止哈利回学校,被关在站台外的哈利和罗恩只能私自开飞车回到学校。罗恩的妹妹金妮被带到密室,墙上留下了密室的血字警告。霍格沃茨面临被迫关闭的危机。哈利终于找到密室入口,迎接他的将是可怕的挑战。最终金妮苏醒,伏地魔留下的神秘日记被销毁,哈利挽救了霍格沃茨。

  • 登峨眉山李白古诗赏析(李白登上峨眉山写下一首诗)

    纵观李白的写景诗篇,无不是以大手笔描绘了雄伟奇特的景象,抒发了李白寄情山水、纵情遨游、狂放不羁的情怀。倘逢骑羊子,携手凌白日。从这段的意思来看,无疑李白着重描绘了峨眉山的高峻与秀丽,奇光异彩。即我此次登上峨眉山,饱览山光之际,感受到了心情的欢快无极。由此可见,李白在饱览山光之际,已然怡情于物外了。综观李白的这首诗,峨眉山的雄伟奇特,无疑令人有人间仙境之感。

  • 南阳市汉画馆开放时间最新消息(南阳市汉画馆位置)

    南阳市汉画馆开放时间开放时间:冬季:8:30-17:00春、夏、秋季:8:30-17:30参观地址:南阳市卧龙区汉画街398号南阳市汉画馆坐落在南阳市卧龙岗南端的龙首处,整个景区占地53360平方米,陈列大楼平面呈“T”字形,建筑总面积达6000平方米,展厅总面积2400平方米。共有9个主展厅和3个临时展厅。展厅内陈列着二百余块精品画像石,按画像内容分类展出,依次为生产劳动、建筑艺术、历史故事、社会生活、天文与神话、角抵、舞乐百戏及祥瑞升仙八大部分。

  • 与n55w相对的名字(曾经最浪漫的表白)

    《志明与春娇》上映十年了。他打开她的手机,将那条短信倒过来。柏原崇的藤井树是所有少女心中的白月光,英俊,忧郁,内敛,敏感。藤井树对暗恋女孩所做的恶作剧用现在的眼光来看,或许幼稚得让人发笑,但正是少年的可爱之处。维米尔最著名的一幅画《戴珍珠耳环的少女》,画中少女微张的双唇,欲语还休的眼神,让这幅画充满了电影式的悬念。跨过百年,我们仍然能从维米尔的画中感受到这份纯粹的爱情。

  • 描写冬天优美句子(怎么写出冬天的美)

    冬天,很多小动物都冬眠了,但小河依然没有睡小河的上面盖了一层冰,人鱼儿不再忍受冬天的寒冷,今天小编就来聊一聊关于描写冬天优美句子?小河的上面盖了一层冰,人鱼儿不再忍受冬天的寒冷。不过,冬天也能给我们带来无限的欢乐和快乐。没有雪的冬天,总是不够唯美,不够浪漫,不够灵动。人们都穿上了厚厚的棉袄。冬姑娘是来接秋姑娘的班,秋带走了菊花的金黄,桂花的芬芳,芙蓉的美丽。而冬,却送来了一片洁白的世界。

  • 精子成活率越长

    例如,通过吃育儿的边缘咀嚼片可以提高,填补微生物蛋白锌和蛋白质硒和蛋白质,提高精子的质量和生存时间,可以使孕期更简单。中华民族医药学认为,其味甘、咸、温性有补肾壮阳益、固精肾、催乳功能。含有丰富多彩的蛋白质、碘、b族维生素、锌、铁、钙、磷等。印度尼西亚医生建议,夫妇在过夫妻生活之前,应该多喝生鸡蛋、牛奶和蜂蜜煮的米粥。年轻夫妇过度渴望,精力消耗大,补充生鸡蛋有助于迅速恢复精神。

  • 眼镜布怎么清洗才干净(眼镜布如何清洗才干净)

    下面更多详细答案一起来看看吧!眼镜布怎么清洗才干净正确清洗眼镜布的方法如下:洗之前最好把盆子用热水消毒。然后把清洗剂倒入盛有温水的盆中。大家要注意,水的温度要适宜,不能过高,将眼镜布浸泡在盆中,用手轻柔眼镜布,直至出现细腻的泡沫,待发现眼镜布上的脏物已清洗干净,换成清水,进行多次洗涤,直至没有泡沫。最后,将眼镜布悬挂于通风向阳处。晒干后就可以使用啦。

  • 7月13日是什么星座(7月13日是啥星座)

    7月13日是什么星座7月13日出生的星座为巨蟹座,巨蟹座出生日期为新历6月22日-7月22日。巨蟹座属于水相星座,位于黄道十二宫的第四个星座,双子座之东,狮子座之西。守护神为赫拉,这使巨蟹很重视自己的家庭。守护星为月亮,月有阴晴圆缺,他们感情真挚,所以不避免地,巨蟹们都有点敏感和情绪化。巨蟹善良温顺同时也是一个母性光芒耀眼的星座,他们对于弱者会很怜悯,和巨蟹一起有一种春风拂面的舒服感觉。

  • 为什么秦始皇要打击吕不韦(秦始皇为何要杀吕不韦)

    吕不韦的权势已经危害到秦王嬴政的君权。吕不韦的这一举动其实客观上促进了各派学说在秦国的统一,为秦统一后的思想建设打下了基础。其次,吕不韦执政期间,继续深化了商鞅以来的变法,使得秦国内政更加稳固,进一步打击了秦帝国的贵族保守势力,为秦始皇大权独揽奠定了基础。

  • 王者取名字大全(适合王者荣耀的网名推荐)

    静夜春水眯眼要微笑,今天小编就来聊一聊关于王者取名字大全?接下来我们就一起去研究一下吧!王者取名字大全静夜春水眯眼要微笑贫僧法号圆寂你太天真给脸拿稳满分可爱陽光比我耀眼倾城般的骚年夏季孤岛晴空蓝色の妖姬凌丝何必再念胭脂不二情书双人面具唯他是命暖心向阳痞味小污女偽文藝少籹倾城笑等爱的玫瑰温情可人拈花一笑成殇萌男神会发光欲与君行雾月凌猛与萌醉解心语犇羴骉余生最爱逗比代表