C Primer Plus Notes 12

1、

声明结构的过程和定义结构变量的过程可以组合成一个步骤。

struct book {

char title20;

char author20;

float value;

} library;

2、

初始化结构:

struct book library = {

"The Pious Pirate and the Devious Damsel",

"Renee Vivotte",

1.96

};

也可以使用指定初始化器:(可以按照任意顺序使用)

struct book gift = { .value = 10.99 };

struct book surprise = {

.value = 25.99,

.author = "James Broadfool",

.title = "Rue for the Toad"

};

3、

在指定初始化器后面的普通初始化器,为指定成员后面的成员提供初始值。另外,对特定成员的最后一次赋值才是它实际获得的值。

eg:

#include <stdio.h>

struct Student {

int id;

char name20;

int age;

float score;

};

int main( )

{

struct Student s1 = {

.id = 1001, // 指定初始化 id

"Alice", 20, 85.5 // 普通初始化器:从id后面的成员开始

// "Alice" → name 20 → age 85.5 → score

};

...

};

eg:

struct book gift = { .value = 18.90,

.author = "Philionna Pestle",

0.25};

赋给value的值是0.25,因为它在结构声明中紧跟在author成员之后。新值0.25取代了之前的18.90。

4、

结构变量名并不是结构的地址,因此要在结构变量名前面加上 & 运算符。

5、

在有些系统中,一个结构的大小可能大于它各成员大小之和。因为系统对数据进行校准的过程中产生了一些"缝隙"。

6、

barney.income == (*him).income == him->income

// 假设 him(一个结构指针) == &barney(一个结构变量)

7、

C允许把一个结构赋值给另一个结构,即使成员是数组,也能完成赋值。但是数组不能这样做。另外,还可以把一个结构初始化为相同类型的另一个结构。

8、

函数不仅能把结构本身作为参数传递,还能把结构作为返回值返回(把结构的信息从被调函数传回主调函数)。

9、

typedef用于为已存在的数据类型创建一个新的名称。

eg:

typedef char * STRING;

STRING name, sign; // 等价于 char *name, char *sign;

如果用#define的话则如下

#define STRING char *

STRING name, sign; // 等价于 char *name, sign; 这导致只有name才是指针

typedef struct {

float x;

float y;

}rect;

rect r1 = { 3.0, 6.0 };

rect r2;

上述代码等价于:

struct {

float x;

float y;

}r1 = { 3.0, 6.0 };

struct {

float x;

float y;

}r2;

注:使用typedef时要记住,typedef 并没有创建任何新类型,它只是为某个已存在的类型增加了一个方便使用的标签。

10、

一些声明示例:

int board88; // 一个内含int数组的数组

int **ptr; // 一个指向指针的指针,被指向的指针指向int类型

int *risks10; // 一个内含10个元素的数组,每个元素都是一个指向int的指针

int (*rusks)10; // 一个指向数组的指针,该数组内含10个int类型的值

int *oof34; // 一个 3 x 4 的二维数组,每个元素都是指向int的指针

int (*uuf)34; // 一个指向 3 x 4 的二维数组的指针,该数组中内含int类型值

int ( *uof3 )4; // 一个内含3个指针元素的数组,其中每个指针都指向一个内含4个int类型元素的数组

注:

①:数组名后面的 和函数名后面的( )具有相同的优先级。它们比 * 的优先级高。

②: 和 ( )的优先级相同,都是从左往右结合。

③: int *oof34;

3 比 * 的优先级高,由于从左到右结合,所以3先与 oof 结合。因此,oof 首先是一个内含3个元素的数组。然后再与4结合,所以 oof 的每个元素都是内含 4 个元素的数组。* 说明这些元素都是指针。最后,int 表明了这 4 个元素都是指向 int 类型的指针。

④: int (*uuf)34;

圆括号()使得 * 先与 uuf 结合,说明 uuf 是一个指针,所以 uuf 是一个指向 3 x 4 的 int 类型二维数组的指针。

11、

char *fump(int); // 返回字符指针的函数

char (*frump)(int); // 指向函数的指针,该函数的返回类型为char

char (*flump3)(int); // 内含3个指针的数组,每个指针都指向返回类型为char的函数

12、

typedef int arr55;

typedef arr5 * p_arr5;

typedef p_arr5 arrp1010;

arr5 togs; // togs 是一个内含 5 个 int 类型值的数组

p_arr5 p2; // p2 是一个指向数组的指针,该数组内含 5 个 int 类型的值

arrp10 ap; // ap 是一个内含 10 个指针的数组,每个指针都指向一个内含 5 个 int 类型值得数组

13、

声明一个函数指针时,必须声明指针指向的函数类型。为了指明函数类型,要指明函数签名,即函数的返回类型和形参类型。

eg:

void ToUpper(char *); // 带 char * 类型参数、返回类型是 void 的函数

void (*pf)(char *); // 声明了一个指针 pf ,指向该函数类型

解析:第1对圆括号把 * 和 pf 括起来,表明 pf 是一个指向函数的指针。因此,(*pf)是一个参数列表为(char *)、返回类型为 void 的函数。如果想声明一个指向某类型函数的指针,可以写出该函数的原型后把函数名替换成(*pf)形式的表达式,创建函数指针声明。

void *pf(char *); // pf 是一个返回字符指针的函数

14、

void ToUpper(char *);

void ToLower(char *);

int round(double);

void (*pf)(char *);

pf = ToUpper; // 有效,ToUpper 是该类型函数的地址

pf = ToLower; // 有效,ToLower 是该类型函数的地址

pf = round; // 无效,round 与指针类型不匹配

pf = ToLower(); /* 无效,ToLower()不是地址,且ToLower()的返回类型是void,他没有返回值,不能在赋值语句中进行 赋值。 */

15、

void ToUpper(char *);

void ToLower(char *);

void (*pf)(char *);

char mis\[\] = "Nina Metier";

pf = ToUpper;

(*pf)(mis); // 把 ToUpper 作用于语法一

pf = ToLower;

pf(mis); // 把 ToLower 作用于语法二

解析:

①语法一

由于 pf 指向 ToUpper 函数,那么 *pf 就相当于 ToUpper 函数,所以表达式 (*pf)(mis) 和 ToUpper(mis) 相同。从 ToUpper 函数和 pf 的声明就能看出,ToUpper 和 (*pf) 是等价的。

②语法二

由于函数名是指针,那么指针和函数名可以互换使用,所以 pf(mis) 和 ToUpper(mis) 相同。从 pf 的赋值表达式语句就能看出 ToUpper 和 pf 是等价的。

16、

function1(sqrt); // 传递 sqrt() 函数的地址

function2(sqrt(4.0)); // 传递 sqrt() 函数的返回值

相关推荐
LDR0069 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术9 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript
码云数智-园园9 天前
C++20 Modules 模块详解
java·开发语言·spring
swordbob9 天前
NIO的channel中什么是 fd(File Descriptor,文件描述符)
java·开发语言·nio
源分享9 天前
Java线程同步的多种实现方法(非常详细)
java·开发语言·jvm
Luminous.9 天前
C语言--day30
c语言·开发语言
玖玥拾9 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
何以解忧,唯有..9 天前
Go语言循环语句详解:for、range与循环控制
开发语言·算法·golang
謓泽9 天前
C语言不是语法,是通往机器的地图。
c语言·开发语言
云水一下9 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php