一、数组

1> 数组的定义和初始化

  1. 定义

    ① 数组定义了同种类型数据的集合
    ② 定义数组时,数组必须有固定的长度
  2. 初始化

    ① 如果在定义数组时,初始化数组,数组元素的个数必须是常量
    ② 如果不在定义数组时初始化,数组元素的个数可以是有确定值的变

    ③ 大括号的初始化方式只能在定义时初始化的情况下使用

2> 数组的内存存储细节

  • 为数组分配内存时是从内存的高地址到低地址,而数组元素的存储是从低地址到高地址
  • 数组名为该数组元素在内存中的首地址,是一个指针常量,类型与数组类型一致
  • 可以用&符号来取得每个数据元素的首地址
  • 数组在内存中所占内存的大小可以用sizeof(数组名)/数组长度来计算

3> 使用注意

  • 数组元素的下标是从0开始的
  • 若要访问数组中的多个元素,一般用for循环
  • 可以通过sizeof来计算数组的长度
  • 可以通过下标直接访问数组,也可以通过指针间接访问数组元素

4> 数组名作为函数参数

  • 数组名作为函数参数是传址参数,传递的是数组的首地址
  • 不同通过sizeof来计算数组长度,此时通过sizeof(数组名),计算的是该编译器中指针的长度
  • 数组的长度必须通过参数传递

5> 示例

  • 步骤

    • 将整型数据10, 6, 23, 8, 15存放在一个数组中
    • 对数组中的元素进行从小到达排序
    • 输出排序后数组中的元素
  • 代码

    #include <stdio.h>
    //将数组按从小到大排序
    void sortTheArray(int array[], int count);
    //逐个输出数组中的元素
    void printTheArray(int array[], int count); int main()
    {
    //定义一个数组并初始化
    int array[]= {10, 6, 23, 8, 15};
    //存储数组元素的个数
    int count; //计算数组的个数
    count = sizeof(array) / sizeof(int); //逐个输出排序前数组中的元素
    printTheArray(array, count); //将数组按从小到大排序
    sortTheArray(array, count); //逐个输出排序后数组中的元素
    printTheArray(array, count); return 0;
    } //将数组按从小到大排序
    void sortTheArray(int array[], int count)
    {
    //用于循环遍历数组
    int i,j,k;
    //中间变量,用于交换数组的两个元素
    int temp; //选择排序
    for (i = 0; i < count-1; i++)
    {
    k = i;
    for (j = i + 1; j < count; j++)
    {
    if (array[j] < array[k])
    {
    temp = array[k];
    array[k] = array[j];
    array[j] = temp;
    }
    }
    }
    } //逐个输出数组中的元素
    void printTheArray(int array[], int count)
    {
    for (int i = 0; i < count; i++)
    {
    printf("%d\t", array[i]);
    }
    printf("\n");
    }

二、字符串

1> 基本使用

  • C语言中用字符数组来表示字符串
  • 字符串用%s格式输出
  • string.h文件中声明了字符串相关的操作函数

2> 字符串的结束标志'\0'

  • 字符串末尾会有'\0'结束标志,其ASCII码值为0
  • 字符串的操作函数是以'\0'为结束符,若没有结束符,这些操作函数可能会操作其他危险的数据
  • 将字符串常量赋值给char类型的指针变量,则该变量存储的是字符串常量的首地址

3> 字符串的输入

  1. scanf函数

    ① scanf函数默认以空格、'\n'和'\t'键作为字符串结束的标志
    ② 可以用格式%[^c]来控制以指定字符c作为字符串结束的标志
  2. gets函数

    ① 可以输入包含空格和'\t'的字符串,以'\n'作为字符串结束标志
    ② gets函数不会判断上限,仅遇到'\n'结束
    ③ 用于接收字符串的缓冲区必须足够大,否则会发生溢出,引发bug
  3. getchar函数

    ① 可以通过循环使用getchar函数来输入任意的字符,来组成字符串
    ② 要对末尾的'\n'进行处理,将其转化为'\0'

三、指针

1> 基本使用

  • 指针变量的内容为内存地址,内存地址是一个机器相关量
  • 指向指针的指针,其内容为所指向指针的地址
  • 通过符号*来访问指针变量所指向地址存储的内容,并可进行修改
  • 指针所指向的内存空间存储变量的类型,与定义指针的类型一致
  • 指针作为函数参数,是一个传址参数
  • 指针可以作为函数参数用于返回函数的执行结果
  • 可以使用指针数组来代替多维数组

2> 使用注意

  • 定义指针变量时的符号*只是一个符号,没有任何实际的意义
  • 定义指针变量时用常量将其初始化,此指针变量的内容将不能被修改
  • 不能间接访问没有初始化的指针变量
  • 若使用一阶指针,不要将地址存储到指针变量所指向的内容
  • 若指针指向的变量类型与定义的类型不一致,可能会影响间接访问的内容
  • sizeof函数的返回值为unsigned long类型,输出格式为%zd
  • 若返回值类型为指针类型,返回值是一个地址

3> 指向函数的指针

  • 定义格式 void (*p)(int ),这是定义一个无返回值,有一个整型参数的指向函数的指针变量

  • 通常用函数名为指向函数的指针变量赋值,函数名表示函数在内存中存储的首地址

  • 通过指针变量调用函数的两种方式

     ① p( );
    ② (*p)();

四、指针与数组

1> 基本使用

  1. 通常定义一个与数组同类型的指针变量来指向数组的首地址
  2. 通过指针的自增自减运算来间接访问数组元素
  3. 可以用指针变量加上下表来访问数组元素

2> 使用注意

  1. 指针运算是以定义指针类型在内存中所占存储空间的字节数为单位的
  2. 下标绝不会比指针更有效率,但指针有时可能比下标更有效率
  3. 数组名和指针不能等同

四、结构体

1> 基本使用

  • 结构体定义了多个不同类型数据的集合,是构造类型的一种
  • 结构体可以将某个对象的一组属性组合在一起
  • 结构体的成员可以是基本数据类型,也可以是其他构造类型,如结构体
  • 可以在定义结构体时用大括号为其初始化,用点语法可以实现机构提成员的乱序赋值
  • 结构体数组用于定义具有多个属性的多个同种类型的对象

2> 使用注意

  • 定义结构体不会分配内存空间,只有定义结构体变量时才会为变量分配内存空间
  • 结构体变量所占内存空间的大小为所有成员变量中占内存空间最大的变量所占内存空间的整数倍
  • 结构体变量之间可以赋值,实际上是全部成员变量之间的赋值
  • 结构体变量的名字是该结构体在内存中的首地址
  • 不能定义同名结构体
  • 尽量不要再代码块内定义结构体,避免造成作用域问题

3> 定义结构体变量的三种方式

  • 在定义结构体的同时定义结构体变量,重用性差
  • 先定义结构体,在用这种类型定义结构体变量
  • 用typedef为结构体定义一个新的类型名,用这个新类型名定义这种类型的结构体变量

4> 指向结构体的指针

  • 可以定义一个结构体类型的指针来指向该种类型的结构体变量

  • 通过指针间接访问结构体指针变量的两种方式

     ① (*p).name,(p为指向结构体变量的指针,name为结构体变量的成
    员变量的名字)
    ② p->name

五、枚举

1> 基本使用

  • 用于定义一个具有固定取值的变量
  • 枚举类型变量的定义与结构体类型变量的定义相似

2> 使用注意

  • 枚举类型的成员变量实际上存储的是整型常量,默认从0开始编号
  • 可以指定枚举类型的成员变量的编号规则

六、综合示例

  • 步骤

    • 定义一个Person结构体,属性包含:名字、性别
    • 名字用字符串表示
    • 性别用枚举表示
    • 定义一个函数输出结构体变量的信息
  • 代码

    #include <stdio.h>
    #include <string.h>
    //定义一个枚举类型,用于存储性别
    typedef enum
    {
    sexMan, sexWoman, sexUnknown
    } Sex; //定义一个结构体类型,用于存储某个人的姓名和性别属性
    typedef struct
    {
    char name[20]; //姓名
    Sex sex; //性别
    } Person; //声明一个函数,用于打印某个人的信息
    void printThePerson(Person *p); int main()
    {
    //定义一个结构体变量p
    Person p; //输入姓名,存放到结构体的name属性中
    printf("请输入一个人的姓名\n");
    //使用%[^\n]控制一'\n'字符作为字符串的结束字符
    scanf("%[^\n]", p.name); //输入性别,存放到结构体的sex属性中
    printf("请输入一个人得性别(0:Man,1:Woman,2:Unknown)\n");
    scanf("%d", &p.sex); //打印结构体变量p的相关信息
    printThePerson(&p); return 0;
    } void printThePerson(Person *p)
    {
    char *str = NULL;
    //将枚举值sex转换成相应的字符串
    switch (p->sex)
    {
    case 0:
    str = "Man";
    break;
    case 1:
    str = "Woman";
    break;
    case 2:
    str = "Unknown";
    break; default:
    break;
    }
    printf("这个人的姓名为:%s\t性别为:%s\n", p->name, str);
    }

C语言-06-复杂数据类型的更多相关文章

  1. C语言-06复杂数据类型-04 结构体

    结构体的说明(构造类型) 数组:只能由多个相同类型的数据构成 结构体:可以由多个不同类型的数据构成 ,结构体的类型是不存在的,自己定义 int main() { // 1.定义结构体类型 定义类型的时 ...

  2. C语言-06复杂数据类型-03指针

    指针变量的定义 变量类型 *变量名; #include <stdio.h> int main() { // 指针就一个作用:能够根据一个地址值,访问对应的存储空间 // 指针变量p前面的i ...

  3. C语言-06复杂数据类型-02字符串

    #include <stdio.h> int main() { //char name[] = {'i', 't', 'c', 'H', 's', 't', '\0'}; char nam ...

  4. C语言-06复杂数据类型-01数组

    01-数组 #include <stdio.h> int main() { // 使用注意 // 都是正确写法 //int ages[5] = {10 , 11, 12, 67, 56}; ...

  5. C语言的基本数据类型长度

    PS:以下内容是在Xcode的编辑器64位环境下的测试结果,网上有关于64位和32位各数据类型存在的差异,请自行online search. main.m #import <Foundation ...

  6. Go 语言的基本数据类型

    Go 语言的基本数据类型 0)变量声明 var 变量名字 类型 = 表达式 例: 其中“类型”或“= 表达式”两个部分可以省略其中的一个. 1)根据初始化表达式来推导类型信息 2)默认值初始化为0. ...

  7. Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器

    Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...

  8. Go语言基础之数据类型

    Go语言基础之数据类型 Go语言中有丰富的数据类型,除了基本的整型.浮点型.布尔型.字符串外,还有数组.切片.结构体.函数.map.通道(channel)等.Go 语言的基本类型和其他语言大同小异. ...

  9. [日常] Go语言圣经--复合数据类型,数组习题

    go语言圣经-复合数据类型 1.以不同的方式组合基本类型可以构造出来的复合数据类型 2.四种类型——数组.slice.map和结构体 3.数组是由同构的元素组成——每个数组元素都是完全相同的类型——结 ...

  10. C语言复习————基本数据类型、运算符和表达式

    数据类型/运算符/表达式 主要分两部分介绍,第一部分介绍常用的数据类型,例如:常量和变量/整型/实型/字符型:第二部分介绍算数运算符和算数表达式以及赋值运算符和逗号运算符. 一. 常用的数据类型 1. ...

随机推荐

  1. 设计前沿:25款精妙的 iOS 应用程序图标

    在这篇文章中,我为大家精心挑选的25款巧妙设计的 iOS 应用程序图标,会激发你未来的工作.苹果的产品总是让人爱不释手,设计精美,对用户使用体验把握得淋漓尽致,iPhone.iPad.iPod和 iM ...

  2. Mysql学习笔记(六)增删改查

    PS:数据库最基本的操作就是增删改查了... 学习内容: 数据库的增删改查 1.增...其实就是向数据库中插入数据.. 插入语句 insert into table_name values(" ...

  3. 分享几个cocos2dx的小游戏

    先上几个自己写的,因为最近要用cocos2dx,所以就边学边开发几个小游戏玩玩,有捕鱼,连连看,还有打地鼠!都不算完整的项目,不过拿来学习还是可以的,或者在基础上再二次开发,扩展自己! 1:捕鱼的 先 ...

  4. 2013/11/22工作随笔-缓存是放在Model层还是放在Controller层

    web网站的典型代码框架就是MVC架构,Model层负责数据获取,Controller层负责逻辑控制,View层则负责展示. 一般数据获取是去mysql中获取数据 但是这里有个问题,我们不会每次请求都 ...

  5. 点餐APP 冲刺三总结

    一转眼所有的冲刺都完成了,而今次的冲刺主要是完善数据库,而我们 也成功地实现了,虽然过程很艰辛,但是我们每一个人都学习到了很多新 知识,这是最好的收获.因为今学期没有软件工程的课程,所以大家都是 利用 ...

  6. nodejs+express+jade给我baby做个小相册

    去年年底迎来了my little star.从此人生多了一个最重要的牵挂.生了宝宝全家人都太忙了.最近宝宝稍微大点了,终于有空可以研究下技术了.这是14年第一帖.废话不多了.开始吧 1.安装NTVS ...

  7. ANT自动打包U3D安卓项目研究笔记

    概述 因项目使用Atlassian Stash作为项目源码管理端,且其支持Ant命令自动编译,可使其根据最新的代码自动打包,故产生该研究Ant打包的任务.在此将研究过程及一些相关知识整理记录在此. 本 ...

  8. ViewData和TempData以及Session的小结

    ViewData一般用在从控制器向页面上传递数据. Public ActionResult Show() { ViewData["message"]="你好"; ...

  9. BI之SSAS完整实战教程1 -- 开篇, BI简介 & SSAS简介

    文章提纲 商业智能(BI, Business Intelligence)基本概念 SSAS(SQL Server Analysis Services)相关工具(开发.管理和客户端) 总结 一.商业智能 ...

  10. Go eclipse plugin

    Installation Requirements: Eclipse 4.5 (Mars) or later. Java VM version 8 or later. Gocode and Go or ...