一个存储区的地址应该是它自身大小的整数倍(双精度浮点类型存储区的地址只需要是4的整数倍),这个规则叫数据对齐,结构体内部的存储区通常也需要遵守数据对齐的规则,数据对齐有可能导致结构体相邻子存储区之间有空隙

  1. /*
  2. * 数据对齐和补齐演示
  3. * */
  4. #include <stdio.h>
  5. typedef struct {
  6. char buf[2];
  7. int num;
  8. } tmp;
  9. typedef struct {
  10. char ch1;
  11. int num;
  12. char ch2;
  13. } tmp1;
  14. int main() {
  15. printf("sizeof(tmp)是%d\n", sizeof(tmp));
  16. printf("sizeof(tmp1)是%d\n", sizeof(tmp1));
  17. return 0;
  18. }

结构体存储区的大小必须是它所包含的占地最大,基本类型子存储区大小的整数倍(如果这个基本类型子存储区是doule类型的则结构体存储区的大小只需要是4的整数倍),这个规则叫数据补齐,数据补齐可能造成结构体最后会多占用一些无效的字节

枚举也可以用来创建新的数据类型,枚举类型存储区就是整数类型存储区,枚举类型存储区在使用的时候只能存放有限的几个整数,枚举类型也需要先声明然后才能使用,声明枚举类型的时候需要使用enum关键字,声明枚举类型的时候还需要提供一组名称,计算机为每个名称分配一个对应的整数,只有这些整数才能记录到枚举类型的存储区里.不同枚举类型存储区能记录的整数范围不同,计算机把从0开始的非负数按顺序分配给枚举类型里的所有名称,可以在声明枚举类型的时候指定把某个整数分配给某个名称,这个名称后面的所有名称被分配的整数也会随着改变

  1. /*
  2. * 枚举类型演示
  3. * */
  4. #include <stdio.h>
  5. int main() {
  6. enum /*season*/ {CHUN, XIA = 5, QIU, DONG};
  7. printf("QIU是%d\n", QIU);
  8. return 0;
  9. }

联合也可以用来创建数据类型,联合也需要先声明然后才能使用,声明联合的时候需要使用union关键字,联合的所有子存储区所占的内存互相重叠,联合所有成员变量存储区的开始地址都一样,联合存储区的大小就是最大子存储区的大小,联合类型的存储区可以当作多种不同类型的存储区使用,每个成员变量代表了一种可选的类型

  1. /*
  2. * 联合演示
  3. * */
  4. #include <stdio.h>
  5. typedef union {
  6. int num;
  7. float fnum;
  8. } tmp;
  9. int main() {
  10. tmp utmp = {0};
  11. printf("&(utmp.num)是%p\n", &(utmp.num));
  12. printf("&(utmp.fnum)是%p\n", &(utmp.fnum));
  13. printf("sizeof(tmp)是%d\n", sizeof(tmp));
  14. return 0;
  15. }

记录普通类型存储区地址的指针叫做一级指针,记录一级指针存储区地址的指针叫做二级指针,二级指针也需要先声明然后才能使用,声明二级指针的时候需要写两个*

  1. /*
  2. * 二级指针演示
  3. * */
  4. #include <stdio.h>
  5. int main() {
  6. int num = 0;
  7. int *p_num = #
  8. int **pp_num = &p_num; //二级指针声明语句
  9. **pp_num = 10;
  10. printf("num是%d\n", num);
  11. *pp_num = NULL;
  12. printf("p_num是%p\n", p_num);
  13. return 0;
  14. }

二级指针名称前使用**可以表示捆绑的普通类型存储区,二级指针名称前使用*可以表示捆绑的一级指针存储区

如果把指针数组里第一个指针的地址记录到一个二级指针里就可以通过这个二级指针找到指针数组里的每个指针,这个时候可以把二级指针看作指针数组的代表,二级指针不可以代表二维数组

  1. /*
  2. * 二级指针形式参数演示
  3. * */
  4. #include <stdio.h>
  5. typedef struct {
  6. int row;
  7. int col;
  8. } pt;
  9. typedef struct {
  10. pt center;
  11. int radius;
  12. } circle;
  13. void larger(const circle *p_cl1, const circle *p_cl2, circle **pp_cl) {
  14. *pp_cl = (circle *)(p_cl1->radius >= p_cl2->radius ? p_cl1 : p_cl2);
  15. }
  16. int main() {
  17. circle cl1 = {0}, cl2 = {0}, *p_cl = NULL;
  18. printf("请输入一个圆的位置:");
  19. scanf("%d%d%d", &(cl1.center.row), &(cl1.center.col), &(cl1.radius));
  20. printf("请再输入一个圆的位置:");
  21. scanf("%d%d%d", &(cl2.center.row), &(cl2.center.col), &(cl2.radius));
  22. //p_cl = larger(&cl1, &cl2);
  23. larger(&cl1, &cl2, &p_cl);
  24. printf("比较大的圆是((%d, %d), %d)\n", p_cl->center.row, p_cl->center.col, p_cl->radius);
  25. return 0;
  26. }

无类型指针有可能实际记录的是一级指针的地址,这个时候就必须首先把它强制类型转换成二级指针然后才能使用

二级指针通常作为函数的形式参数使用,被调用函数可以通过二级指针形式参数向调用函数传递一个地址数据

C语言里函数也有地址,函数的名称可以表示函数的地址,函数指针可以用来记录函数的地址,函数指针也需要先声明然后才能使用,函数指针的声明可以根据函数声明变化得到

  1. /*
  2. * 函数指针演示
  3. * */
  4. #include <stdio.h>
  5. int add(int num, int num1) {
  6. return num + num1;
  7. }
  8. int main() {
  9. int (*p_func)(int, int) = add; //函数指针声明
  10. printf("add是%p\n", add);
  11. printf("结果是%d\n", p_func(3, 8));
  12. return 0;
  13. }

函数指针也分类型,不同类型的函数指针适合与不同格式的函数捆绑

函数指针可以用来调用函数

标准C语言(12)的更多相关文章

  1. 关于标准C语言的预定义宏【转】

    标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义.下面预定义宏表,被我抄了下来. __LINE__  当 ...

  2. 【部分原创】标准C语言的优先级、结合性、求值顺序、未定义行为和非确定行为浅析

    零. 优先级    在C++ Primer一书中,对于运算符的优先级是这样描述的:     Precedence specifies how the operands are grouped. It ...

  3. 标准SQL语言的用法

    原文链接:http://www.ifyao.com/2015/05/18/%E6%A0%87%E5%87%86%E7%9A%84sql%E8%AF%AD%E8%A8%80%E4%BD%BF%E7%94 ...

  4. 关于标准C语言的预定义宏

    标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义.下面预定义宏表,被我抄了下来.__LINE__  当前 ...

  5. UML标准建模语言与应用实例

    一.基本信息 标题:UML标准建模语言与应用实例 时间:2012 出版源:科技创新导报 领域分类:UML标准建模语言 面向对象 系统分析与设计 二.研究背景 问题定义:UML建模语言用图形来表现典型的 ...

  6. UML(统一建模语言)是通用的可视化标准建模语言。由构造块、公共机制、构架三部分组成。

    UML UML(统一建模语言)是通用的可视化标准建模语言.由构造块.公共机制.构架三部分组成. 1.构造块:包括基本的UML建模元素(类.接口.用例等).关系(关联关系.依赖关系.泛化关系.实现关系) ...

  7. 标准C 语言总结

    ***************C语言****************** --day01-- Linux是一个和Windows类似的操作系统 通常通过终端软件使用Linux操作系统 终端软件里只能使用 ...

  8. python标准库介绍——12 time 模块详解

    ==time 模块== ``time`` 模块提供了一些处理日期和一天内时间的函数. 它是建立在 C 运行时库的简单封装. 给定的日期和时间可以被表示为浮点型(从参考时间, 通常是 1970.1.1 ...

  9. 标准C语言的输入输出流(i/o)方法详解

    cppreference.com -> 标准 C I/O ->详细说明 标准 C I/O clearerr 语法: #include <stdio.h> void cleare ...

随机推荐

  1. linux常用命令(9)nl命令

    nl命令在linux系统中用来计算文件中行号.nl 可以将输出的文件内容自动的加上行号!其默认的结果与 cat -n 有点不太一样, nl 可以将行号做比较多的显示设计,包括位数与是否自动补齐 0 等 ...

  2. Python之数组

    前言 由于Python的数据结构较为灵活,长期使用java编程的我,有时候可能就搞混淆了.此时,记录一些骚操作. 不定长二维数组 array = [4,65,46,57,5]; array2d = [ ...

  3. python网络应用篇

    正则表达式 import re #引入正则表达式模块  使用re.match/search函数进行匹配(区别:match只匹配字符串的开始,如果不符合正则表达式,则匹配失败,返回None,而searc ...

  4. hbase的hue部署和使用

    1.组件版本信息 zookeeper hadoop hbase     hue           zookeeper-3.4.12 hadoop-3.0.3 hbase-2.1.5 4.4.0 2. ...

  5. appium环境搭建(一)----安装appium

    一.安装appium Appium官方网站:http://appium.io/,官方首页给出了appium的安装步骤. > brew install node # get node.js > ...

  6. <<大道至简>>伪代码

    import.java.大道至简.* public class YuGong { public static void main(String [] args) throws IOException ...

  7. mysql jdbc url

    地址为jdbc:mysql://localhost:3306/mymiaosha?characterEncoding=utf-8时访问时可能会出现下图提示 地址改为jdbc:mysql://local ...

  8. sqlserver安装和踩坑经历

    sqlserver安装和踩坑经历 下载 下载 安装 大致是按照这个来的 安装教程 出错 windows系统安装软件弹出"Windows installer service could not ...

  9. python-socketserver实例

    import socketserver class MyTCPHandler(socketserver.BaseRequestHandler): def handle(self): while Tru ...

  10. IntelliJ IDEA setup JDK无效

    参考 问题现象:功能全部爆红,总是提示“setup JDK”,设置JDK后无效.但程序能够正常编译和运行. 解决方法:  File -> Invalidate Caches/Restart -& ...