《C和指针》笔记30:函数声明数组参数、数组初始化方式和字符数组的初始化

文章目录

  • [1. 函数声明数组参数](#1. 函数声明数组参数)
  • [2. 数组初始化方式](#2. 数组初始化方式)
    • [2.1 静态初始化](#2.1 静态初始化)
    • [2.2 自动变量初始化](#2.2 自动变量初始化)
  • [2.2 字符数组的初始化](#2.2 字符数组的初始化)

1. 函数声明数组参数

下面两个函数原型是一样的:

cpp 复制代码
int strlen( char *string );
int strlen( char string[] );
  • 可以使用任何一种声明,但哪个"更加准确"呢?

答案是指针。因为实参实际上是个指针,而不是数组。同样,表达式sizeof string的值是指向字符的指针的长度,而不是数组的长度。

  • 为什么函数原型中的一维数组形参无需写明它的元素数目?

因为函数并不为数组参数分配内存空间。形参只是一个指针,它指向的是已经在其他地方分配好内存的空间。这个事实解释了为什么数组形参可以与任何长度的数组匹配 ------它实际传递的只是指向数组第1个元素的指针 。另一方面,这种实现方法使函数无法知道数组的长度。如果函数需要知道数组的长度,它必须作为一个显式的参数传递给函数

2. 数组初始化方式

数组初始化的方式类似于标量变量的初始化方式------也就是取决于它们的存储类型。

2.1 静态初始化

存储于静态内存的数组只初始化一次,也就是在程序开始执行之前 。程序并不需要执行指令把这些值放到合适的位置,它们一开始就在那里了。这个魔术是由链接器完成 的,它用包含可执行程序的文件中合适的值对数组元素进行初始化。如果数组未被初始化,数组元素的初始值将会自动设置为零。当这个文件载入到内存中准备执行时,初始化后的数组值和程序指令一样也被载入到内存中。因此,当程序执行时,静态数组已经初始化完毕。

2.2 自动变量初始化

由于自动变量位于运行时堆栈中,执行流每次进入它们所在的代码块时,这类变量每次所处的内存位置可能并不相同。在程序开始之前,编译器没有办法对这些位置进行初始化 。所以,自动变量在缺省情况下是未初始化的。如果自动变量的声明中给出了初始值,每次当执行流进入自动变量声明所在的作用域时,变量就被一条隐式的赋值语句初始化。这条隐式的赋值语句和普通的赋值语句一样需要时间和空间来执行。数组的问题在于初始化列表中可能有很多值,这就可能产生许多条赋值语句。对于那些非常庞大的数组,它的初始化时间可能非常可观。

  • 如何选择初始化方式:静态初始化 or 自动变量初始化?

这个问题等同于问:当数组的初始化局部于一个函数(或代码块)时,在程序的执行流每次进入该函数(或代码块)时,每次都对数组进行重新初始化呢。如果答案是否定的,你就把数组声明为static,这样数组的初始化只需在程序开始前执行一次。

2.2 字符数组的初始化

字符数组初始化的时候可以是这样:

cpp 复制代码
char message[] = { 'H', 'e', 'l', 'l', 'o', 0 };

这个方法当然可行。但除了非常短的字符串,这种方法确实很笨拙。因此,语言标准提供了一种快速方法用于初始化字符数组:

cpp 复制代码
char message[] = "Hello";

尽管它看上去像是一个字符串常量,实际上并不是 。它只是前例的初始化列表的另一种写法。

  • 如何分辨字符串常量和这种初始化列表快速记法呢?

它们是根据它们所处的上下文环境进行区分的。

①当用于初始化一个字符数组 时,它就是一个初始化列表

②在其他任何地方 ,它都表示一个字符串常量

cpp 复制代码
char message1[] = "Hello";
char *message2 = "Hello";

这两个初始化看上去很像,但它们具有不同的含义。前者初始化一个字符数组的元素 ,而后者则是一个真正的字符串常量。这个指针变量被初始化为指向这个字符串常量的存储位置,如下图所示:

参考

  1. 《C和指针》
相关推荐
qq_401700417 小时前
嵌入式用Unix时间的优势及其C语言转换
服务器·c语言·unix
智者知已应修善业13 小时前
【51单片机普通延时奇偶灯切换】2023-4-4
c语言·经验分享·笔记·嵌入式硬件·51单片机
晚风(●•σ )13 小时前
C++语言程序设计——11 C语言风格输入/输出函数
c语言·开发语言·c++
X***489613 小时前
C源代码生成器
c语言·开发语言
合作小小程序员小小店15 小时前
桌面安全开发,桌面二进制%恶意行为拦截查杀%系统安全开发3.0,基于c/c++语言,mfc,win32,ring3,dll,hook,inject,无数据库
c语言·开发语言·c++·安全·系统安全
oioihoii18 小时前
C++语言演进之路:从“C with Classes”到现代编程基石
java·c语言·c++
历程里程碑21 小时前
各种排序法大全
c语言·数据结构·笔记·算法·排序算法
树在风中摇曳21 小时前
带哨兵位的双向循环链表详解(含 C 代码)+ LeetCode138 深度解析 + 顺序表 vs 链表缓存机制对比(图解 CPU 层级)
c语言·链表·缓存
雨落在了我的手上1 天前
C语言入门(二十一):字符函数和字符串函数(1)
c语言
embrace991 天前
【C语言学习】结构体详解
android·c语言·开发语言·数据结构·学习·算法·青少年编程