C语言——声明总结

int *f();//返回指向int指针的函数。.

int (*pf)(); //指向返回int的函数的指针。pf is pointer to function returning int

C语言的声明中分为”类型”和”标识符”,把标识符取出后,剩下就是类型名(基本类型和派生类型,派生类型是由结构体、联合体、数组、函数、指针这些类型本身和有;之所以被叫做派生类是因为他们可以无限的派生出很多派生类型)。

解读C的声明(英语版)

  • 找到标识符(变量名或函数)名称。
  • 从标识符最近的地方开始依照”小括号、数组[ ]、函数()、指针* “的顺序解读。
  • 用of,to,returning连接。
  • 追加最左边的数据类型修饰符。
  • 也可用倒叙中文版。

举例:用英语的方式解读

int (*func_p)(double)

//1.找到函数名:func_p
    func_p is

//2.存在小括号(*func_p)
    func_p is pointer to

//3.遇见了函数标识符(*func_p)(double)
    func_p is pointer to function(double) returning

//4.追加数据类型修饰符int
    func_p is pointer to function(double) returning int //翻译过来就是:func_p是返回int的函数的指针。

举例:用中文的方式解读

int (*func_p)(double)

//1.找到函数名:func_p
    func_p

//2.存在小括号(*func_p)
    func_p是一个指针(此时找到描述func_p的形容词)

//3.遇见了函数标识符(*func_p)(double)
    func_p是一个指向函数的指针(此时找到描述指针的形容词)

//4.追加数据类型修饰符int
    func_p是一个指向返回值是int类型的函数的指针(此时找到描述函数的形容词)

练习:

 double (*p)[3];//指向double类型的数组(长度为3)的指针。
 double *pp [3];//double类型的指针的数组(长度为3)。
 int (*func_table[10])(int a);//指向返回值为int的函数(参数为int)的数组(长度为10)。

const关键字:const修饰的是紧跟在它后面的单词。

//成为只读的不是src,而是src所指向的对象。
char *strcpy(char *dest,const char *src){
     src = NULL;//编译通过
     *src = 'a';//报错
}
char *strcpy(char *dest, char const *src){
     src = NULL;//编译通过
     *src = 'a';//报错
}
//将src自身定义为只读
char *strcpy(char *dest, char *const src){
    src = NULL;//报错
    *src = 'a';//编译通过
}
char *strcpy(char *dest,const char *const src){
    src = NULL;//报错
    *src = 'a';//报错
}
char const* src 等价于 char const *src

const修饰结构体:定义为const的只读,只是结构体所指向的对象自身,不包括结构体指向对象所指向的对象。

typedef struct {
    char *title;
    int price;
    char isbn[32];
} BookData;

void regist_book(BookData const bookData){
    bookData .title = 'a';//报错
    *bookData .title = 'a';//编译通过
}

上面例子的解释:
这里写图片描述

typedef关键字:用于给某些类型定义别名。

typedef char *String;//String是指向char的指针
String hoge[10];//hoge是指向char的指针的数组

数组的特殊说明

下标运算符[]可以忽略元素个数(中括号里面的数字不生效)的几种情况:

  • 当做函数的形参声明时,只有在这种情况下,int s[]和int *s才具有相同的意义

     void f(int s[]){}
     void f(int *s){}//上面会被编译器自动解读为这种情况。
    
  • 根据初始化表达式可以确定数组大小时。

         int a[] = {1,2,3};
    
  • 使用extern声明全局变量时。

     file_1.c中的int a[100];
     file_2.c中的extern int *a;
    

关于数组的初始化

//一维数组初始化
int s[3] = {1,2};
    printf("%d",s[1]);//2
    printf("%d",s[2]);//0
    printf("%d",s[4]);//地址值
//多维数组的初始化:观察运行结果即可发现规律。
int a[][3] = {
        {1,2,3,8},
        {4,5},
        {6}
};

printf("%d",a[0][3]);//4
printf("%d",a[0][8]);//0
printf("%d",a[0][9]);//内存地址值

字符串常量

str和str1具有相同的含义,编译器会对字符串常量做特殊处理。

char str[] = "abc";
char str1[] = {'a','b','c','\0'};
char str[] = "abc";//允许修改
     str[0] = 'd';
char *str1[] = "abc";//不允许
     str1[0] = 'd';
char str[] = {};//编译不通过
    str = "abc";

练习两个复杂声明

 int atexit(void (*func)(void));//返回int的函数,参数是指向返回void没有参数的函数的指针
 void (*signal(int sig,void (*func)(int)))(int);//signal是返回“指向返回void参数为int的函数的指针“的函数,
                                                // 它有两个参数,一个是int,另一个是“指向返回void参数为int的函数指针”

指针的数组和数组的数组

//指针的数组
    char *color_name[] = {
        "red","green","blue",
   };

这里写图片描述

//数组的数组
char color_name1[][6] = {
     "red","green","blue",
};

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值