C Primer Plus Notes 12

1、

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

struct book {

char title[20];

char author[20];

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 name[20];

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 board[8][8]; // 一个内含int数组的数组

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

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

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

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

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

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

注:

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

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

③: int *oof[3][4];

3\] 比 \* 的优先级高,由于从左到右结合,所以\[3\]先与 oof 结合。因此,oof 首先是一个内含3个元素的数组。然后再与\[4\]结合,所以 oof 的每个元素都是内含 4 个元素的数组。\* 说明这些元素都是指针。最后,int 表明了这 4 个元素都是指向 int 类型的指针。 ④: int (\*uuf)\[3\]\[4\]; 圆括号()使得 \* 先与 uuf 结合,说明 uuf 是一个指针,所以 uuf 是一个指向 3 x 4 的 int 类型二维数组的指针。 11、 char \*fump(int); // 返回字符指针的函数 char (\*frump)(int); // 指向函数的指针,该函数的返回类型为char char (\*flump\[3\])(int); // 内含3个指针的数组,每个指针都指向返回类型为char的函数 12、 typedef int arr5\[5\]; typedef arr5 \* p_arr5; typedef p_arr5 arrp10\[10\]; 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() 函数的返回值

相关推荐
CoderYanger41 分钟前
动态规划算法-简单多状态dp问题:11.按摩师
开发语言·算法·leetcode·职场和发展·动态规划·1024程序员节
CoderYanger1 小时前
动态规划算法-路径问题:10.地下城游戏
开发语言·算法·leetcode·游戏·职场和发展·动态规划·1024程序员节
liu****1 小时前
11.字符函数和字符串函数(二)
c语言·开发语言·数据结构·c++·算法
@小白鸽1 小时前
1.2.1创建型设计模式
开发语言·设计模式
沐知全栈开发1 小时前
R 绘图 - 函数曲线图
开发语言
qq_548674931 小时前
Go的env和bashrc的GOROOT配置不同
linux·开发语言·golang
freexyn1 小时前
Matlab自学笔记六十九:多项式求值、求根、积分和求导
开发语言·笔记·matlab
灵犀坠1 小时前
前端高频知识点汇总:从手写实现到工程化实践(面试&开发双视角)
开发语言·前端·javascript·tcp/ip·http·面试·职场和发展