微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 硬件工程师文库 > 所有C语言数组和指针的知识都在这里了!|周立功手把手教你学C语言编程

所有C语言数组和指针的知识都在这里了!|周立功手把手教你学C语言编程

时间:08-01 来源:ZLG致远电子 点击:

 

因为标准C认为数组元素的个数n不是常量,虽然编译器似乎已经"看到"了n的值,但int array[n]要在运行时才能读取变量n的值,所以在编译期无法确定其空间大小。使用符号常量定义数组长度的正确形式如下:

#define N 10

int array[N];

 

即可根据实际的需要修改常量N的值。

 

由于数组元素下标的有效范围为0~N-1,因此data[N]是不存在的,但C语言并不检查下标是否越界。如果访问了数组末端之后的元素,访问的就是与数组不相关的内存。它不是数组的一部分,使用它肯定会出问题。C为何允许这种情况发生呢?这要归功于C信任程序员,因为不检查越界可以使运行速度更快,所以编译器没有必要检查所有的下标错误。因为在程序运行之前,数组的下标可能尚未确定,所以为了安全起见,编译器必须在运行时添加额外代码检查数组的每个下标值,但这样会降低程序的运行速度。C相信程序员能编写正确的代码,这样的程序运行速度更快。但并不是所有的程序员都能做到这一点,越界恰恰是初学者最容易犯的错误,因此要特别注意下标的范围不能超出合理的界限。

 

(3)变量的地址与类型

 

当将变量data[0]、data[1]和data[2]作为&的操作数时,&data[0]是指向变量data[0]的指针,&data[1]是指向变量data[1]的指针,&data[2]是指向变量data[2]的指针。data[0]、data[1]和data[2]变量的类型为int,&data[0]、&data[1]和&data[2]指针的类型为int *const,即指向常量的指针,简称常量指针,其指向的值不可修改。比如:

int a; 

int * const ptr = &a;

ptr = NULL;                          // 试图修改,则编译报警

&a = NULL;                        // 试图修改,则编译报警

 

同理,&data是指向变量data的指针,那么data是什么类型?

 

按照声明变量的规约,将标识符data取出后,剩下的"int [3]"就是data的类型,通常将其解释为由3个int组成的数组类型,简称数组类型。其目的是告诉编译器需要分配多少内存?3个元素的整数数组,data类型测试程序详见程序清单 1.20。

 

程序清单 1.20 data类型测试程序

1     #include

2

3     void f(int x);

4     int main(int argc, char *argv[]) 

5     { 

6            int data[3]; 

7            f(data); 

8            return 0; 

9    } 

 

通过编译器提示的警告,"funtion: 'int' differ in levels of indirection from 'int [3]'",说明数组变量data的类型为不是int而是int [3]数组类型。由于在设计C语言时,过多地考虑了开发编译器的便利。虽然设计编译器更方便了,却因为概念的模糊给初学者造成了理解上的困难。实际上数组应该这样定义:

int [3] data;

 

即int是与[3]结合的。&data到底是什么类型?

 

当data作为&的操作数时,则&data是指向data的指针。由于data的类型为int [3],因此&data是指向"int [3]数组类型"变量data的指针,简称数组指针。其类型为int (*)[3],即指向int [2]的指针类型。为何要用"()"将"*"括起来?

 

如果不用括号将星号括起来,那么"int (*)[3]"就变成了"int *[3]",而int *[3]类型名为指向int的指针的数组(元素个数3)类型,这是设计编译器时约定的语法规则。

 

&data的类型到底是不是"int (*)[3]"?其验证程序范例详见程序清单 1.21。

 

程序清单 1.21 &data类型测试程序

1     #include

2     int main(int argc, char *argv[]) 

3     {

4            int data[3]

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top