1. 函数指针(function pointer):

函数指针是指向函数的指针变量。

通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。

函数指针可以像一般函数一样,用于调用函数、传递参数。

函数指针变量的声明:

typedef int (*fun_ptr)(int,int);

例子:https://www.runoob.com/cprogramming/c-fun-pointer-callback.html

sub:指针函数是返回指针的函数,详见我上一篇文章。

2.回调函数(Callback function):

函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数。

"

以下是来自知乎作者常溪玲的解说:

你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。

"

意思简单来说就是:你现在定义的A函数的参数包含了一个你现在还不知道的B函数,所以你在参数中做了一个B函数指针以便引用这个B函数。 一旦引用的这个B函数被定义了,你就可以在runtime使用你的A函数。

例子:https://www.runoob.com/cprogramming/c-fun-pointer-callback.html

sub:size_t 是一种数据类型,近似于无符号整型,但容量范围一般大于 int 和 unsigned。这里使用 size_t 是为了保证 arraysize 变量能够有足够大的容量来储存可能大的数组.

 3.字符串(string):

在 C 语言中,字符串实际上是使用 null 字符 '\0' 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。

下面的声明和初始化创建了一个 "Hello" 字符串。由于在数组的末尾存储了空字符,所以字符数组的大小比单词 "Hello" 的字符数多一个。

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};   (一般正常人不会用这种)(不需要把 null 字符放在字符串常量的末尾。C 编译器会在初始化数组时,自动把 '\0' 放在字符串的末尾。)

char greeting[] = "Hello";  (比较通用,和其他语言很像,注意“[ ]”,因为C里面string是char的array。)

常见操作:

strcpy(s1, s2);  复制字符串 s2 到字符串 s1。

strcat(s1, s2);   连接字符串 s2。

strlen(s1);    返回字符串 s1 的长度。

strcmp(s1, s2);   如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。

strchr(s1, ch);   返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。

strstr(s1, s2);   返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。

sub:

strlen 与 sizeof的区别:

strlen 是函数,sizeof 是运算操作符,二者得到的结果类型为 size_t,即 unsigned int 类型。

sizeof 计算的是变量的大小,不受字符 \0 影响;

而 strlen 计算的是字符串的长度,以 \0 作为长度判定依据。

 4.结构体(struct):

a.定义:

C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。

假设我们有一个电子图书馆,我们可以用结构体来定义一本书及其属性: 1.标题 2.作者。。。之类。

为了定义结构,您必须使用 struct 语句。struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:

struct Books {

  char  title[50];

  char  author[50];

  char  subject[100];

  int   book_id;

}book;

在一般情况下,tag 、member-list、variable-list 这 3 部分(对应代码里面的Books, char  title[50]; , book)至少要出现 2 个。

sub :

1.不同的定义方式产生的结构体可以被视为不同的类型,无法相等(不管成员是不是一样).

2.结构体的成员可以包含其他结构体,也可以包含指向自己结构体类型的指针,而通常这种指针的应用是为了实现一些更高级的数据结构如链表和树等。

3.可以在定义的时候初始化,跟变量一样。

详见:https://www.runoob.com/cprogramming/c-structures.html

b. 结构访问还有使用:

为了访问结构的成员,我们使用成员访问运算符(.)。成员访问运算符是结构变量名称和我们要访问的结构成员之间的一个句号。您可以使用 struct 关键字来定义结构类型的变量。

比如 你要访问 Book1 的title --- Book1.title   (如果学过面对对象编程的朋友估计感觉很眼熟)

c.结构作为函数参数:

您可以把结构作为函数参数,传参方式与其他类型的变量或指针类似。您可以使用上面实例中的方式来访问结构变量:

void printBook( struct Books book ){

。。。

。。。

。。。

}

d.指向结构的指针:

struct Books *struct_pointer;        定义

struct_pointer = &Book1;            结构变量的地址

struct_pointer->title;               指向该结构的指针访问结构的成员

e.位域:

有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有 0 和 1 两种状态,用 1 位二进位即可。为了节省存储空间,并使处理简便,C 语言又提供了一种数据结构,称为"位域"或"位段"。

所谓"位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。

位域和结构体的定义基本上差不多,只不过需要多加 位域长度 。

struct bs{

   int a:8;

   int b:2;

   int c:6;

}data;

说明 data 为 bs 变量,共占两个字节。其中位域 a 占 8 位,位域 b 占 2 位,位域 c 占 6 位。

使用时这两种都可以:1. data.a   2. data->a

sub:

1.一个位域存储在同一个字节中,如一个字节所剩空间不够存放另一位域时,则会从下一单元起存放该位域。也可以有意使某位域从下一单元开始。

2.由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。如果最大长度大于计算机的整数字长,一些编译器可能会允许域的内存重叠,另外一些编译器可能会把大于一个域的部分存储在下一个字中。

3.位域可以是无名位域,这时它只用来作填充或调整位置。无名的位域是不能使用的.

4.位域在本质上就是一种结构类型,不过其成员是按二进位分配的。

5.结构体变量的首地址能够被其最宽基本类型成员的大小所整除。

6.结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding)。即结构体成员的末地址减去结构体首地址(第一个结构体成员的首地址)得到的偏移量都要是对应成员大小的整数倍。

引用:https://www.runoob.com/cprogramming/c-structures.html

C学习笔记(5)--- 指针第二部分,字符串,结构体。的更多相关文章

  1. C语言笔记 08_函数指针&回调函数&字符串&结构体&位域

    函数指针 函数指针是指向函数的指针变量. 通常我们说的指针变量是指向一个整型.字符型或数组等变量,而函数指针是指向函数. 函数指针可以像一般函数一样,用于调用函数.传递参数. 函数指针变量的声明: / ...

  2. 【学习笔记】【C语言】结构体

    1.定义结构体变量的3种方式 1> 先定义类型,再定义变量(分开定义) struct Student {    int age; }; struct Student stu;  2> 定义 ...

  3. golang学习笔记14 golang substring 截取字符串

    golang学习笔记14 golang substring 截取字符串golang 没有java那样的substring函数,但支持直接根据 index 截取字符串mystr := "hel ...

  4. 【Unity Shaders】学习笔记——SurfaceShader(一)认识结构

    [Unity Shaders]学习笔记——SurfaceShader(一)认识结构 转载请注明出处:http://www.cnblogs.com/-867259206/p/5595747.html 写 ...

  5. 5、数组&字符串&结构体&共用体&枚举

    程序中内存从哪里来 三种内存来源:栈(stack).堆(heap).数据区(.date): 栈(stack) 运行自动分配.自动回收,不需要程序员手工干预: 栈内存可以反复使用: 栈反复使用后,程序不 ...

  6. 菜鸟学习-C语言函数参数传递详解-结构体与数组 分类: C/C++ Nginx 2015-07-14 10:24 89人阅读 评论(0) 收藏

    C语言中结构体作为函数参数,有两种方式:传值和传址. 1.传值时结构体参数会被拷贝一份,在函数体内修改结构体参数成员的值实际上是修改调用参数的一个临时拷贝的成员的值,这不会影响到调用参数.在这种情况下 ...

  7. 传入的结构体指针强制转为实例化结构体*v

    struct val *v = (struct val *)arg;//传入的结构体指针强制转为实例化结构体*v struct val{ int num1; int num2; }; void *te ...

  8. GO语言学习(十六)Go 语言结构体

    Go 语言结构体 Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型. 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合. 结构体表示一项记录,比如保存图 ...

  9. 结构体指针,C语言结构体指针详解

    结构体指针,可细分为指向结构体变量的指针和指向结构体数组的指针. 指向结构体变量的指针 前面我们通过“结构体变量名.成员名”的方式引用结构体变量中的成员,除了这种方法之外还可以使用指针. 前面讲过,& ...

  10. C++笔记(4)——引用及结构体

    引用 C++中有一个很方便的语法叫做引用,作用就是使得函数能够对传入的参数作出全局有效的改动.用法很简单,就是在传入参数的类型后面加上&就可以指明传入的参数是引用. 例子: #include ...

随机推荐

  1. [靶场实战]:SQL注入-显错注入

    SQL注入的本质:就是将用户输入的数据当作代码带入执行. 注入条件: 1.用户能控制输入 2.能够将程序原本执行的代码,拼接上用户输入的数据进行执行 首先检查是否存在注入点 Rank1: 构造语句 ? ...

  2. July 7th, 2019. Week 27th, Sunday

    We laughed and kept syaing "see you soon", but inside we both knew we would never see each ...

  3. 05-Django后台管理和视图

    Django的后台管理可以方便的生成管理页面,使用前先准备如下: 1.本地化 语言和时区的本地化,修改settings.py文件 # LANGUAGE_CODE = 'en-us' LANGUAGE_ ...

  4. python使用beautifulsoup4爬取酷狗音乐

    声明:本文仅为技术交流,请勿用于它处. 小编经常在网上听一些音乐但是有一些网站好多音乐都是付费下载的正好我会点爬虫技术,空闲时间写了一份,截止4月底没有问题的,会下载到当前目录,只要按照bs4库就好, ...

  5. Codeforces Round #597 (Div. 2) F. Daniel and Spring Cleaning 数位dp

    F. Daniel and Spring Cleaning While doing some spring cleaning, Daniel found an old calculator that ...

  6. 你想了解的「SpringCloud」都在这里

    前言: 之前我们已经了解了「什么是微服务?」,现在我们开始了解「微服务」关键字下比较热门的「Spring Cloud」... 一.传统架构发展史 部分引用自:从架构演进的角度聊聊Spring Clou ...

  7. golang数据结构之栈

    stack.go package stack import ( "errors" "fmt" ) type Stack struct { MaxTop int ...

  8. spring cloud 2.x版本 Gateway自定义过滤器教程

    前言 本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server.eureka-client.eureka ...

  9. 避免python二维列表append一维列表时浅拷贝问题

    原始问题: 由于浅拷贝原因,使得当a列表变动时,b列表也发生变动 解决办法: 如上图所示,添加的时候添加新列即可,类似新建一个列表,使得与原有列表a不共用同一个内存

  10. IT兄弟连 Java语法教程 数组 数组的初始化

    Java语言中数组必须先初始化,然后才可以使用.所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值. 这时有人会问,能不能只分配内存空间,不赋初始值呢?答案是肯定不行的,一旦为数组 ...