美文网首页
分析C语言的声明(1)

分析C语言的声明(1)

作者: Mr_Bluyee | 来源:发表于2018-07-28 21:07 被阅读12次

C语言声明的语法有时会带来严重的问题。C语言声明的语法对于编译器的处理来说并不是什么大不了的事,但是对于一般的程序员,它却会成为障碍。C语言声明的语法渗透于整个语言使用的方方面面,毫不夸张的说,正是由于在组合类型方面的笨拙行为,C语言被显著且毫无必要的复杂化了。

C语言的声明模型之所以如此晦涩,原因之一是早期在设计C语言时,出现的一种C语言设计哲学,要求对象的声明形式与它的使用形式尽可能相似。一个int类型的指针数组被声明为 int *p[3];并以*p[i]这样的表达式引用或使用指针所指向的int数据,所以它的声明形式和使用形式非常相似。

这种做法的好处是各种不同操作符的优先级在“声明“和”使用“时是一样的。它的缺点在于操作符的优先级过于复杂,程序员需要记住特殊的规则才能推断出int *p[3]到底是一个int型的指针数组,还是一个指向int数组的指针。

数组指针与指针数组:

数组指针(也称行指针)
定义 int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。
如要将二维数组赋给一指针,应这样赋值:

int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
 p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
 p++;       //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]

所以数组指针也称指向一维数组的指针,亦称行指针。

指针数组
定义 int *p[n];
[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1时,则p指向下一个数组元素,这样赋值是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:

int *p[3];//这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
int a[3][4];
p++; //该语句表示p数组指向下一个数组元素。注:此数组每一个元素都是一个指针,所以要分别赋值。
for(i=0;i<3;i++){
  p[i]=a[i];
}

数组指针和指针数组在指向二维数组时,其引用是一样的,比如要表示数组中i行j列一个元素:

*(p[i]+j)
*(*(p+i)+j)
(*(p+i))[j]
p[i][j]

C语言的声明所存在的最大的问题是你无法以一种人们所习惯的自然方式从左向右阅读——一个声明,在ANSI C引入volatile和const关键字后,情况就更糟糕了。由于这些关键字只能出现在声明中(而不是使用中),这就使得现如今声明形式和使用形式能完全对的上号的例子越来越少了。

如果想要把什么东西的类型强制转换为指向数组的指针,就不得不使用下面的语句来表示这个强制类型转换:

char (*j)[20];  /*j是一个指向数组的指针,组内右20个char元素。*/
j = (char (*)[20])malloc(20);

如果把星号两边看上去多余的括号拿掉,代码会变成非法的。
涉及指针和const的声明可能会出现几种不同的顺序:

const int * grape;
int const * grape;
int * const grape;

最后一种情况指针是只读的,在前两种情况下,指针所指向的对象是只读的。当然,如果要对象和指针都只读,如下面两种声明所示:

const int * const grape;
int const * const grape;

相关文章

  • 分析C语言的声明(1)

    C语言声明的语法有时会带来严重的问题。C语言声明的语法对于编译器的处理来说并不是什么大不了的事,但是对于一般的程序...

  • 分析C语言的声明(2)

    声明器(declarator) 声明器是所有声明的核心,简单的说,声明器就是标识符以及与它组合在一起的任何指针、函...

  • 复杂声明 | C语言

    今天看了《C专家编程》里的'分析C语言的声明'一章,终于懂了C语言的复杂声明是怎么解析的。虽然在平时写代码的时候用...

  • C语言类型系统与复杂声明

    Ref: Linuc C编程一站式学习 C语言类型系统 不完全类型 分析复杂声明

  • 从C语言的变量声明到Objective-C中的Block语法

    从C语言的变量声明到Objective-C中的Block语法 从C语言的变量声明到Objective-C中的Blo...

  • 函数变参的使用

    介绍C/C++,java,和go语言对函数变参的使用。 1. C/C++语言的变参 1.1 变参函数声明 变参函数...

  • 数组-C\Java

    ·C语言:·C语言中的语法:声明、赋值·声明:标示代码格式·赋值:变量获得值的方式变量种类:标量(scalar)、...

  • Effective Objective-C 2.0读书笔记

    1、所有Objective-C语言的对象都必须这样声明:NSString *someString = @"the ...

  • 0基础学习C语言第七章:数组(2)

    C语言 多维数组 C 语言支持多维数组。多维数组声明的一般形式如下: type name[size1][size2...

  • GO

    一、基础 1.变量 强类型语言 声明单个变量Go语言在声明变量时,自动对变量对应的内存进行初始化操作,不同于C语言...

网友评论

      本文标题:分析C语言的声明(1)

      本文链接:https://www.haomeiwen.com/subject/vqlamftx.html