多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

数组与字符串 | C指针基础(二)

数组与字符串 | C指针基础(二) 数组、字符串和指针 | C指针基础二数组名 arr、arr 与 arr[0] 打印结果为何相同字符串与指针利用指针读取数组数组名 arr、arr 与 arr[0] 打印结果为何相同先运行下面这段程序#includestdio.hintmain(){intarr[10]{0};printf(%d\n,arr);printf(%d\n,arr);printf(%d\n,arr[0]);return0;}运行后你会发现三个 printf 打印出来的结果完全相同并且输出的都是地址。这是因为在表达式中数组名 arr 会退化为指向首元素的指针其值等于arr[0]而arr取的是整个数组的地址虽然类型不同但地址数值也与首元素地址相同因此三者打印结果一致。也就是说在C语言中数组名本质上是一个指针存储的是该数组第一个元素的内存地址。数组名的取地址和取第一个元素的地址是同一个操作。字符串与指针我们知道在 C 语言中字符串本质上也是一种字符数组因此可以仿照上一节的方式运行下面的程序#includestdio.hintmain(){charname[10];charname1[10];charname2[10];scanf(%s,name);scanf(%s,name1);scanf(%s,name2[0]);printf(%s\n,name);printf(%s\n,name1);printf(%s\n,name2[0]);return0;}运行后你会发现分别向 name、name1、name2 输入内容后三个 printf 都能正确打印出最开始输入的字符串而不是像上一节那样打印地址。这是因为两次示例使用的格式占位符不同数组示例中使用%d打印的是指针本身保存的地址数值而字符串示例中使用%sprintf会沿着传入指针所指向的首字符开始逐个读取并输出字符直到遇到\0结束符因此最终打印出来的是完整的字符串内容。对比示例// 数组示例%d 输出地址printf(%d\n,arr);// 输出类似一串地址数值// 字符串示例%s 输出字符串printf(%s\n,name);// 输出类似hello你输入的内容也就是说在 C 语言中字符串是字符数组字符串名同样可以看作指向首字符的指针name、name、name[0]在数值上都等于字符串首字符的地址。利用指针读取数组前面已经知道数组名在表达式中会退化为指向首元素的指针因此除了用下标访问还可以利用指针来读取数组元素。先看下面的程序#includestdio.hintmain(){intarr[10]{10001,20003,0};printf(%d\n,*arr);// 等价于 arr[0]printf(%d\n,*(arr1));// 等价于 arr[1]return0;}运行后会输出10001 20003根据上一篇笔记可知*是解引用运算符用来取出指针所指向的内容而数组名arr本身就表示首元素地址所以*arr就是取出第一个元素等价于arr[0]。同理arr 1并不是把地址简单地加 1 个字节而是按照指针指向的类型自动步进。因为arr是int类型数组arr 1会指向下一个int元素也就是arr[1]的地址再对它解引用就得到第二个元素的值。下面两组写法完全等价printf(%d\n,arr[0]);// 下标方式读取第一个元素printf(%d\n,*arr);// 指针方式读取第一个元素printf(%d\n,arr[1]);// 下标方式读取第二个元素printf(%d\n,*(arr1));// 指针方式读取第二个元素推广到一般情况arr[i]与*(arr i)等价这就是 C 语言中指针与数组之间的联通关系。
返回列表