C语言可以通过malloc()函数在运行时分配内存,这个函数接受一个参数:所需的字节数。malloc()函数会找到合适的空闲内存块,这样的内存是匿名的。也就是说,malloc函数分配内存,但是不会为其赋名。然而,它确实返回动态分配内存块的首字节地址。因此,可以把该地址赋给一个指针变量,并使用指针访问这块内存。
由于char表示1字节,malloc()的返回类型通常被定义为指向char的指针。然而,从ANSI C标准开始,C使用一个新的类型:指向void的指针。该类型相当于一个“通用指针”。malloc函数可以用于返回指向数组的指针、指向结构的指针等,所以通常该函数的返回值会被强制转换为匹配的类型。在ANSI C中,应该坚持使用强制类型转换,提高代码的可读性。然而,把指向void的指针赋给任意类型的指针完全不用考虑类型匹配的问题。如果malloc()分配内存失败,将返回空指针。
程序12.14 dyn_arr.c
#include#include int main(void) { double * ptd; int max = 0; int number; int i = 0; puts("What is the maximum number of type double entries?"); if (scanf("%d", &max) != 1){ puts("Number not correctly entered -- bye."); exit(EXIT_FAILURE); } ptd = (double *) malloc(max * sizeof (double)); if (ptd == NULL){ puts("Memory allocation failed. Goodbye."); exit(EXIT_FAILURE); } puts("Enter the values (q to quit):"); while (i < max && scanf("%lf", &ptd[i]) == 1) ++i; printf("Here are your %d entries:n", number = i); for (i = 0; i < number; i++){ printf("%7.2f ", ptd[i]); if (i % 7 == 6) putchar('n'); } if (i % 7 != 0) putchar('n'); puts("Done."); free(ptd); return 0; }
下面是程序的运行结果,程序通过交互的方法首先让用户确定数组大小,我们设置数组大小为5。后来虽然输入了6个数字,但程序只处理前5个数。
What is the maximum number of entries? 5 Enter the values (q to quit): 20 30 35 25 40 80 Here are your 5 entries: 20.00 30.00 35.00 25.00 40.00 Done.
C90新增了两个属性:constancy和volatility,这两个属性可以分别用关键字const和volatile来声明,以这两个关键字创建的类型是限定类型(qualified type)。C99标准新增了第3个限定符:restrict,用于提高编译器优化。C11标准新增了第4个限定符:_Atomic。C11提供了一个可选库,由stdatomic.h管理,以支持并发程序设计,而且_Atomic是可选支持项。
5.1 const类型限定符这里需要补充第10节中的const内容
第四节和第十节中介绍过const。以const关键字声明的对象,其值不能通过赋值或递增、递减来修改。在ANSI兼容的编译器中,以下代码:
const int nochange; nochange = 12;
编译器会报错。但是可以初始化const变量。因此,下面的代码没问题:
const int nochange = 12;
该声明让nochange成为只读变量。初始化后,就不能再改变它的值。
可以用const关键字创建不允许修改的数组:
const int days1[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
5.1.1 在指针和形参声明中使用const
声明普通变量和数组时使用const关键字很简单。指针则复杂一些,因为要区别是限定指针本身为const还是限定指针指向的值为const。下面的声明:
const float * pf;
pf指针指向的值不能被改变,而pf本身的值可以改变。例如,可以设置该指针指向其他const值。相比之下,下面的声明:
float * const pt;
创建的指针pt本身的值不能更改。pt必须指向同一个地址,但是它所指向的值可以改变。下面的声明:
const float * const ptr;
表明ptr既不能指向别处,它所指向的值也不能改变。



