C专家编程:第三章:分析C语言的声明

本文详细解析了C语言中的指针概念及应用,包括const修饰符的多种用法、复杂声明的解读、结构体与联合的内存布局等,并通过实例展示了结构体在实际编程中的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、关于const的声明:

const int *p:指针p指向的内容不变;

int const *p:指针p指向的内容不变;

 

int * const p:指针p不变;

 

const int * const p:指针和指针指向的内容都不变;

int const * const p:指针和指针指向的内容都不变。

2、一些合法的声明:

1)int(* fun( ))( ): 函数( fun() )的返回值是一个指向参数为空,返回值类型为int 的函数指针。

2)int(* foo())[]: foo( )函数的返回值是一个指向int型数组的指针。

3)int(* foo[ ])(): foo数组里的元素是指向参数为空返回值为int型的函数指针。

3、关于结构:

1)struct {  ….. } plum, pomegranate, pear;

可以在struct关键字后加一个可选的“结构标签”;

struct  fruit_tag { …..} ;

struct  fruit_tag  plum, pomegranate, pear;

2)跟结构有关的参数传递问题:

参数在传递时首先尽可能的存放到寄存器中(追求速度)。注意,int型变量 i 跟只包含一个int型成员的结构变量s 在参数传递时的方式可能完全不同。一个int型参数一般会被传递到寄存器中,而结构参数则很可能被传递到堆栈中。

在结构体中放置数组:struct  s_tag{ inta[100]; };可以把它当作第一等级的类型,用赋值语句拷贝整个数组,以传值调用的方式把它传递到函数,或者把它作为函数的返回类型:

struct  s_tag { int a[100];};

struct  s_tag  orange, lime, lemon;

struct  s_tag  twofold( struct s_tag  s)

{

int j;

for(j = 0; j < 100; j++)

{

s.a[j]  *= 2;

}

return s;

}

int main()

{

int I;

for(i = 0; i < 100; i++)

{

lime.a[i] = 1;

}

lemon = twofold(lime);

orange = lemon;    //给整个结构赋值

return 0;

}

4、关于联合:在联合中,所有的成员都从偏移地址零开始存储。

联合可以节省存储空间。

5、关于枚举:enum sizes { small  =  7,medium, large  =  10, humungous };

省却情况下,整型值从零开始,如果对列表中的某个标识符进行了赋值,那么紧接其后的那个标识符的值就比所赋的值大1。枚举有个有点,#define定义的名字一般在编译时被丢弃,而枚举名字则通常一直在调试器中可见,可以在调试代码时使用他们。

6、char *  const  * (* next)();------- next是一个指针,它指向一个函数,该函数返回另一个指针,该指针指向一个类型为char的常量指针。

       char  *(* c[10])(int **p);----------c[10]是具有10个元素的数组,里面的元素类型是函数指针,其所指向的函数的返回值是一个指向char的指针,该函数的参数是一个指向指针的指针。

7、void (*signal (int  sig,  void (* func) (int) ) )  (int):

void (*signal (       )) (int);  signal是一个函数,它的返回值是函数指针该指针所指向的函数接受一个int型 的参数并返回void。

void (*func) (int) ;   func是一个函数指针,该指针指向的函数接受一个int 参数,返回值是void。

typedef代替:

typedef  void (*ptr_to_func)  (int);

ptr_to_func  signal (int, ptr_to_func);

8、typedef和define的区别:

1)可以用其他类型说明符对宏类型名进行扩展,但对typedef所定义的类型名不能。

#define  peach  int

unsigned  peach  i;--------------------OK

 

typedef  int banana;

unsigned  banana  I;--------------------ERROR

2)在连续的变量声明中,typedef定义的类型能够保证声明中所有的变量均为同一种类型。

#define  int_ptr  int  *

int_ptr  chalk, cheese;

经过宏扩展:

int * chalk, cheese;--------chalk是指向int型的指针,cheese是int型变量。

 

typedef  char * char_ptr;

char_ptr  Bentley,Rolls_Royce;

Bentley, Rolls_Royce都表示指向char的指针。

9、结构体的声明:

typedef  struct  my_tag { int  i; }  my_type

将 struct  my_tag  { int i; }重命名为 my_type;定义一个结构体可用my_type  potato或者struct  my_tag potato。

1)结构体最好不用typedef;

2)最好不省略struct关键字;

3)以“_tag”结尾的名字来命名结构标签。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值