C-函数指针,指针函数,构造体之结构体

指针函数:

返回值是指针的函数

指针函数的定义:

一般形式:

类型说明符 *函数名(形参表){

函数体

}

其中, 函数名之前加了’*’ 号表明这是一’指针型函数, 即返回值是一个指针. 类型说明符表示了返回的指针所指向的数据类型

函数指针:

  1. 一个函数在内存中总是占用一段连续的内存区, 而函数名就是该函数所占内存区的首地址——把函数的这个首地址(入口地址) 赋予一个指针变量, 使该指针变量指向该函数. 然后通过指针变量就可以找到并调用这个函数——这种指向函数的指针变量称为”函数指针变量”

类型说明符 (*指针变量名)(函数的参数);

类型说明符:  是指向的函数的返回值类型

函数的参数:  是指向的函数的参数

以上两个如果都没有(void 和 无参)的话, 指针声明的时候也可以改变

就是相当于把函数头中的函数名改成了(*p)

声明

1 int sum(int a, int b);
2 int (*p)(int a, int b);

初始化:

p1 = sum;   // 存的就是函数在内存中的首地址

函数指针变量注意:

  1. 函数指针变量不能进行算术运算, 这是与数组指针变量不同的. 数组指针变量加减一个整数可以使指针移动指向后面或者前面的数组元素, 而函数指针的移动式毫无意义的(函数体内的地址移动基本上是没有意义的)
  2. 函数调用中”(*指针变量名)”的两边的括号不可少, 其中的*不是求值匀速, 跟指针变量声明时一样, 它也只是一种表示符号,  表明该变量是一种指针变量

构造类型开头:

  1. 什么是构造数据类型: 构造数据类型是根据已定义的一个或多个数据类型用构造的方法来定义的——也就是说:一个构造类型的值可以分解成若干个”成员” 或 “元素”. 每个成员都是一个基本数据类型或又是一个构造类型

2.典型的几种构造类型:

数组 array

结构体 struct

共用体(联合体) union

3.结构体:

数组的缺陷: 只能存储同一种数据类型的数据

结构体: 相当于其他高级语言中的 记录

是一种构造类型, 由若干个”成员”组成, 每一个成员可以使一个基本数据类型或者又是一个构造类型

4.用结构体的目的:

  1. 可以忽视数据类型而把功能相同的数据组织起来存在一起, 能够使得在使用时更加方便
  2. 在调用函数的时候, 如果传递参数比较多, 传一个结构体相对而言简单一些, 很多系统自带的函数必须用到结构体
  3. 作用: 可以创建一种新的数据类型, 指定这个新的数据类型的变量是由哪些小便量联合而成的.

5.结构体的声明

 1 struct 结构名{
 2     //成员列表
 3 };
 4
 5 //定义一个学生的结构体
 6 struct stu{
 7     int num;
 8     char name[20];
 9     char sex;
10     float score;
11 };

声明时候的注意事项: 结构体花括号后面有一个分号, 不能省略

6. 注意

  1. 结构体定义完成以后, 计算机并不会给结构体分配内存空间, 而是在定义结构体变量之后分配内存空间
  2. 结构体是定义的一种新的数据类型, 所以在使用结构体变量之前, 需要先定义类型, 然后再声明变量
  3. 命名规范: 每一个单词的首字母大写

7. 定义一个结构体类型的变量

  1. 定义了结构体以后再定义结构体变量

  struct stu stu1;

  //这句话表示定义一个stu1结构体类型的变量

  //stu1是因为是stu类型, 所以stu1可以存放学生的学号, 姓名, 年龄, 成绩;

  //也可以同时定义多个结构体变量

  struct stu stu2, stu3, stu4;

  1. 定义结构体的同时定义结构体变量
1 struct Car{
2     int num;
3     char name;
4 }car1, car2, car3;
  1. 用匿名的结构体来定义结构体变量
1 struct{
2     int num;
3     char color;
4 }car1, car2, car3;

这种方法尽量不要用

  1. 默认值的问题:

    1. 只声明不初始化: 全部是垃圾值
    2. 部分 / 全部初始化:  未初始化的值自动赋0
  2. 作用域问题:
    1. 一般情况下, 跟正常变量一样, 出了其所定义的代码块便失效
    2. 而一个结构体一般是要多出引用, 所以一般情况下是全局的

8.结构体数组

  1. 声明: struct 元素类型 数组名[数组长度]

struct Student students[5];

表示了我们声明了一个长度为5的数组, 数组的名字: students, 数组的长度: 5, 数组元素的类型: struct Student, 所以, 这个数组能够存储 5 个 struct Student 类型的元素

  1. 初始化

    1. 声明以后元素单独初始化
    2. 声明同时完全初始化 / 部分初始化

9. 结构体指针

  1. 格式: struct 结构体类型名称 *指针名 → struct Student *pStu

声明了一个struct Student指针变量, 这个指针变量的类型是struct Student, 这个指针就只能指向struct Student 类型的变量

  1. 初始化步骤:

    1. 取出结构体变量的地址

      1. &
    2. 将地址值赋给指针变量
      1. struct Student xiaoMing = {“小明”, 86};
      2. struct Student *pStu = &xiaoMing;
  2. 结构体指针访问结构体变量: 见LH20160309/struct array结构体数组

10.结构体嵌套

  1. 简单, 略

11.结构体与函数

  1. 结构体作为参数传值, 是值传递
  2. 如果希望函数的内部可以实参结构体变量的值, 那么结构体指针作为参数
  3. 作为返回值:

  

1  struct Student getAStudent(){
2      struct Student s1 = {“xiaoMing”, 81};
3      return s1;
4 }
5 // 不能返回s1的地址, 因为作为局部变量, 函数调用完其地址就释放了
6
7 // 如果要想保持其地址不变, 类比与字符串指针, calloc在堆区申请空间就可以了, 记得free.
时间: 2024-10-05 20:05:33

C-函数指针,指针函数,构造体之结构体的相关文章

结构体,结构体指针作为函数参数的应用笔记

1. 结构体,结构体指针作为函数参数有何区别 #include <stdio.h> #include <string.h> struct animal { char name[30]; int num; }; //使用结构体作为参数 浪费内存 需要建立结构体 void change_struct(struct animal cat) { cat.num = 17; } //函数内部改变需要地址 所以需要指针保存 void change_point(struct animal *ca

串口数据传输当中的共用体和结构体转换

嵌入式系统的串口数据传输都是以字节为单位,但是有些特殊的数据类型,比如float a=231.5,在最底层是如何表示的呢?我们知道float数据类型占用4个字节,实际上在内存当中a=0x43678000,只是嵌入式芯片访问a时,知道a是浮点型数据,所以一次性读取4个字节,而且也按照浮点型的数据表示规定,将a转换为十进制的可读数据231.5.如果我们从串口接收到4个字节数据{0x43,0x67,0x80,0x00},如何把这4个字节的数据转换为float型呢?直接令float a=0x436780

C语言中的结构体,结构体数组

C语言中的结构体是一个小难点,下面我们详细来讲一下:至于什么是结构体,结构体为什么会产生,我就不说了,原因很简单,但是要注意到是结构体也是连续存储的,但要注意的是结构体里面类型各异,所以必然会产生内存对齐的问题.也就是内存里面会有空档. 1.结构体的定义和赋值 结构体是可以直接初始化的,在定义的时候,就可以初始化,而且如果你的结构体中恰好有字符数组的话,这个时候初始化是不错的选择,原因很简单,字符数组只能定义的时候直接初始化 后来就不可以了,后来你就只能用strcpy函数来拷贝初始化了. str

结构体嵌套结构体名

转自:http://atu82.bokee.com/6706799.html 前一段时间在看DDK中例子的时候,看到这样的的结构体定义: typedef struct _COMMON_DEVICE_DATA { PDEVICE_OBJECT Self; BOOLEAN IsFDO; ...... } COMMON_DEVICE_DATA, *PCOMMON_DEVICE_DATA; typedef struct _PDO_DEVICE_DATA { COMMON_DEVICE_DATA; //

12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!

1.gets()函数 问:请找出下面代码里的问题: #include<stdio.h> int main(void) { char buff[10]; memset(buff,0,sizeof(buff)); gets(buff); printf("\n The buffer entered is [%s]\n",buff); return 0; } 答:上面代码里的问题在于函数gets()的使用,这个函数从stdin接收一个字符串而不检查它所复制的缓存的容积,这可能会导致

结构体以及结构体指针——//知识复习//

结构体 struct node { int data; char sex; }s1,s2;                         //-------------变量s1,s2 typedef struct node { int data; char sex; }SS;                           //-------------类型名SS typedef 存在类型名 自定义类型名 结构体指针 typedef struct node { int data; stru

关于结构体里面结构体的申明和使用

申请: typedef struct Vo  {   int Voltage;   float Delay_ms;   char Enable;  }Volt_Def; typedef struct ed  {   float Delay_ms;   int Level;  }Edge_Def; typedef struct Ed_hard  {   Edge_Def a;   Edge_Def b;   Edge_Def c;  }HARD_RESET;  int power_sel = 0x

C语言之结构体以及结构体对齐访问

1:简单理解,结构体就是数组的进一步发展,数据的优点和缺陷在于数据里面是元素类型必须相同,但是结构体没有这个要求,结构体里面元素的类型可以相同也可以不同. 2:结构体的定义: struct student {     int age;     char name[20]; }s1; 上面这种方法是结构体定义的同时定义变量,结构体的定义有两部分组成 struct studen:结构体的类型 s1:类型为struct student的结构体变量,当然还可以用struct studet s2:l来定义

C#调用C/C++动态库 封送结构体,结构体数组

因为实验室图像处理的算法都是在OpenCV下写的,还有就是导航的算法也是用C++写的,然后界面部分要求在C#下写,所以不管是Socket通信,还是调用OpenCV的DLL模块,都设计到了C#和C++数据类型的对应,还有结构体的封装使用.在夸语言调用方面,Java和C#都只能调用C格式导出的动态库,因为C数据类型比较单一,容易映射,两者都是在本地端提供一套与之映射的C#或者Java的描述接口,通过底层处理这种映射关系达到调用的目的. 5月19日学习内容: http://www.cnblogs.co