首页 > 其他分享 >C语言10-指针(多级指针、空指针、野指针),自定义数据类型(枚举enum、结构体struct)

C语言10-指针(多级指针、空指针、野指针),自定义数据类型(枚举enum、结构体struct)

时间:2024-04-12 21:23:05浏览次数:18  
标签:自定义 int 成员 数据类型 枚举 类型 指针 结构

第 12 章 指针 pointer

12.6 多级指针

指向指针的指针称为多级指针

eg:int *ptr1 = #
	int **ptr2 = &ptr1;
	int ***ptr3 = &ptr2;

12.7 空指针

应用场景:
1. 暂时不确定指向的指针,可以在定义的时候先赋值为NULL
2. 有些指针函数,如果内部出现异常无法成功实现功能,可以返回NULL

eg: int *ptr1 = NULL; double *ptr2 = NULL; short (*ptr3)[] = NULL;
	time_t n = time(NULL);

注意事项:空指针 不允许解引用。

12.8 野指针

产生野指针的场景:
1. 未初始化的指针
2. 越界的指针
3. 指向的被销毁的数据

要避免野指针!

总结

1. 指向普通变量的指针
int *、double *、char *、short * .....

2. 指针和数组
int *[]   指针数组
int (*)[] 数组指针

3. 指针和函数
double *(int,int)   指针函数
double (*)(int,int) 函数指针

4. 多级指针
double *** 、 int **

第 13 章 自定义数据类型

C 语言数据类型总结:

整型: char、short、int、long、long long

浮点型:float、double、long double

数组: int []double [10]int[2][3] ...

函数:double (int,int)void () ...

指针:int *double *double (*)[]int (*)(int,int,int) ...

自定义枚举类型

自定义结构体类型

自定义共用体类型

13.1 枚举 enum

① 定义枚举类型

enum 枚举类型名称
{
    枚举元素名称1,
    枚举元素名称2,
    枚举元素名称3
    ...
}

注:

  1. 枚举类型名称 和 枚举元素名称 都需要符合标识符规范
  2. 枚举元素也称为枚举常量、枚举成员、枚举列表项 等,其本质就是一个标识符常量

② 根据 枚举类型 定义 枚举变量

1. 先定义枚举类型,再定义枚举变量
2. 同时定义 枚举类型 和 枚举变量
3. 同时定义 枚举类型 和 枚举变量,并将枚举类型省略
  • 用格式化字符用 %d
  • 枚举元素都是常量
  • 如给枚举变量重新赋值 枚举元素意外的 元素,不推荐这样赋值
  • 可以 printf 直接打印输出 枚举元素的值?

③ 枚举元素的特点

(1)枚举元素的值必须在同一枚举中是【唯一】的
(2)枚举元素的值必须是【整数类型】,通常是int
(3)如果没有为枚举元素指定值,编译器会自动为它们分配值,从0开始,依次递增。
	若只给枚举类型的第一元素赋值为2,后面的元素也会在2的基础上依次递增1的;
	枚举类型的每个元素都可以被赋值,不过必须是整型
(4)定义枚举的时候也可以为枚举元素自定义值,需保证【唯一性】和【整型类型】。——1、2点的结合

13.2 结构体 struct

① 定义结构体类型

struct 类型名称
{
    成员类型 成员名称1;
    成员类型 成员名称2;
    成员类型 成员名称3;
   ...
}

注:结构体类型名称 和 成员名称 都需要符合标识符规范。

② 根据 结构体类型 定义 结构体变量

1. 定义结构体变量
   ① 先定义 结构体类型 ,再定义 结构体变量
   ② 同时定义 结构体类型 和 结构体变量
   ③ 同时定义 结构体类型 和 结构体变量,并省略 结构体类型 的名称
   
2. 结构体变量的 初始化
   ① 先【声明】结构体变量,然后挨个给成员【初始化赋值】
   ② 在声明结构体变量的同时,使用 {} 一次性给成员初始化赋值
   
3. 访问结构体变量的成员
   使用 . 运算符  ————?
   结构体变量名.成员名

函数形参为结构体:void printStudentInfo(struct Student stu)

strcpy (stu1.address, "中国"); ——把 中国 复制给 stu1.address

③ 结构体指针

1.声明结构体指针 语法格式:
    struct 结构体名 *结构体指针变量名;

2.结构体指针访问成员:
    结构体指针可以通过“->” 操作符访问结构体的成员。
    
	指针名->成员名 与 变量名.成员 是等价的
    	变量名.成员——指的是该成员的存放地址
    
    如果指针变量p指向一个结构体变量stu,以下3种用法等价:
        (1)stu.成员名
        (2)(*p).成员名
        (3)p->成员名

eg: struct Student *stu_ptr = &stu;
	// 通过结构体指针,给里面的成员 重新赋值
    stu_ptr->age = 18;		// (*stu_ptr)—>age = 18;
    stu.id = 102;
	// 解引用结构体指针,并重新给对应成员 赋值
    (*stu_ptr).name = "司马懿";
  • sprintf(),用于将格式化数据写入字符串

④ 结构体变量的存储大小

1. 类型对齐
   变量的地址一定是【数据类型长度】的【整数倍】,如 int 类型变量它的地址一定是 4 的倍数
 
2. 结构体对齐
   ① 结构体成员对齐: 【结构体成员地址】的相对于【结构体地址的偏移量】,肯定是自身类型长度的【整数倍】
   ② 结构体整体对齐: 结构体存储大小 肯定是【结构体基准长度】的整数倍,结构体以 基准长度 为对齐单位。
                   大部分情况下,基准长度是最大成员的长度。		
                   		——目前 基准长度 大部分都是16个字节,也就是目前数组类型的最大长度值
                   		——相对于单片机,会有4字节的,一般会 基准长度 和 最大成员的长度比较,取较小值
   ③ 自行设置结构体基准长度  #pragma pack(长度) 		——放在需要设置的结构体上面就行,不需要放在最顶部头文件处


3. 结算结构体变量存储大小的语句:
	printf("%zu \n", sizeof(结构体类型));  // 结构体类型如:struct User

标签:自定义,int,成员,数据类型,枚举,类型,指针,结构
From: https://www.cnblogs.com/petard/p/18132142

相关文章

  • 4.数据类型
    lua有8中数据类型(使用type()函数可以查看变量数据类型)nil:表示一个无效值,相当于c中NULLboolean:两个值true,false(想当与c中bool)number:双精度类型的实浮点string:字符串(形式:str="我是字符串,我不能跨行"或者str='我是字符串,我不能跨行'或者str=[[......
  • WPF自定义Window
    前言我们使用WPF开发客户端软件时,一般来讲都不会直接使用默认的Window样式,因为很难符合项目的风格,所以我们一般会自定义Window,一般有两种方式。WindowStyle=None和自定义Window,本文主要介绍第二种。一、WindowStyle=NoneWindowStyle="None"将Window的整个边框就去掉了,好处是......
  • 二维字符串数组的传参时与指针互转时的问题
    二维数组如何传参二维字符串数组,转char**会导致的问题,以及编译报错要想得到正确的结果,需要按如下方式去写传参:#include<stdio.h>#include<string.h>//intchar_arr_copy(char**dest)//这样定义传参类型将导致编译报错,在低版本的编译器下或者没有报错但是得不到正确......
  • docker network之 自定义网络(重点,多容器时都是使用这个)
    原来的默认使用bridge模式,创建好容器以后,2个容器使用ip地址去ping对方的ip是ok的,但是按照容器的服务名字取ping就失败: 我们知道容器在重启后,ip是可能变化的。所以那总不可能按照ip去访问吧,最好是按照服务名去访问,那怎么处理呢,请看下方:dockernetworklsdockernetworkcrea......
  • java_基础01_数据类型和变量
     1.注释//单行注释/*多行注释*//**javaDoc:文档注释/***@Descriptionhello*//***_ooOoo_*o8888888o*88"."88*......
  • SpringBoot starter 原理及如何自定义 starter
     前言项目的开发要求是不断进化的,而随着时间以及技术的推移,在项目中除了基本的编程语言外,还需要进行大量的应用服务整合。例如,在项目中使用MySQL数据库进行持久化存储,同时会利用Redis作为缓存存储,以及使用RocketMQ实现异构系统整合服务等。但在早先使用Spring开发的......
  • C++ 引用和指针:内存地址、创建方法及应用解析
    C++引用和指针创建引用引用变量是对现有变量的“别名”,它是使用&运算符创建的:stringfood="Pizza";//食物变量string&meal=food;//对food的引用现在,我们可以使用变量名food或引用名meal来引用食物变量:cout<<food<<"\n";//输出Pizzacout<<mea......
  • C语言09-指针(指针数组、数组指针、字符指针),值传递和引用传递,指针和函数,注释写法
    第12章指针pointer12.3指针和数组①数组名可以把数组名当做是存储了首元素地址的常量。//arr的类型表示为int[5]intarr[5]={10,20,30,40,50};②指针数组指针数组(PointerArray)是一个数组,其中的每个元素都是指针。intnum1=10,num2=20,num3=30;//ptr_......
  • 右击canvas画布时,显示自定义菜单
    <style> .clickRightMenu{ width:110px; background-color:#fff; font-size:12px; position:absolute; text-align:left; padding:2px0; border:1pxsolid#ccc; display:none; z-index:100; } .clickRightMe......
  • directive自定义指令把文案转html+输入功能
    文案: "甲方(贷款人):全称:$var<text_aasdrup06rc00>法定代表人/负责人:$var<text_k2s9cffkhls00>地址:$var<text_6356yvx7oag00>\n\n乙方(借款人):全称/姓名:(变量-姓名),身份证号码/统一社会信用代码:(变量-身份证)地址:$var<text_1g9bed61qp7k0>\n\n鉴于:\n\n甲方与乙方于 $var<date_3ld......