C语言学习-复杂数据类型

本文详细介绍了C语言中的复杂数据类型,包括数组的初始化、长度获取、内存存储细节和与函数的交互;字符串的定义、strlen函数的用法;深入探讨了指针的应用,如指针与数组、字符串的结合,以及返回指针的函数和指向函数的指针;此外还讲解了结构体和枚举类型的定义、使用和特性,如结构体内存管理、结构体数组、结构体指针、枚举类型定义及使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组

数组初始化

int a[3]={1,2,3};

int a[]={1,2,3};

int a[8]={[3]=2,[4]=6};用下标对指定值进行初始化

使用注意

1) int a[‘A’]={3,4,5},写法正确,’A’相当于65

2) 如果在定义数组的同时进行初始化,数组下标不能是变量,必须为常量或者空缺

3) int a[];此种写法不对,计算机无法分配空间,会报错

获取数组长度

sizeof(数组名)/sizeof(数组类型);

数组内存存储细节

内存分配地址时寻址是由大到小的,对数组依然适用,但分配数组元素时(即赋值)由小到大赋值,区别于变量的由大到小赋值

数组与函数

1) 数组作为函数参数,可以省略下标。如:void test(int a[])

    注意:此时不能用sizeof来计算函数的形参数组,即sizeof(a)/sizeof(int)不能计算数组的长度

2) 数组作为函数参数,传递的是数组的地址,即指针传递

字符串

字符串的定义

两种定义方式:字符串数组和字符串指针(指针与字符串部分深入介绍)

1) 不是任一字符数组都是字符串(如最后没有’\0’的字符数组)

2) 任何字符串都有’\0’在最后,’\0’为字符串结束符,系统自动添加

strlen函数:计算字符串长度

1) 计算的是字符数,不是字数

2) 计算的字符数不包括’\0’

3) 从某个地址开始计算字符的个数,直到遇到’\0’才结束(只认’\0’)

指针及深入使用

定义格式:变量类型 *变量名;

指针也是一个变量,只不过为只能存储地址的变量,并且任何类型的指针变量都只占用8个字节的存储空间,可以通过指针间接实现一个函数的返回多个值。

指针与数组

可以通过指针访问数组,访问过程中,指针变量的+1不同于整型变量的+1

int型指针变量+1实际内存地址+4char型、long型相同)

指针变量+1,实际内存地址加几取决于该指针变量是哪种类型的指针

指针与字符串

定义字符串的两种方式

1) 利用数组

char name[]=”itcast”;

特点:字符串里面的字符是可以修改的

2) 利用指针

char *name=”itcast”;

特点:字符串其实是一个常量字符串,里面的字符不能修改

使用场合:

  • 字符串内容经常修改时,选用数组(如:输入)

  • 字符串内容不需要修改,而且这个字符串经常使用时,选用指针

返回指针的函数

char *test()
{
         return “itcast”;
}

等价于

(char *)test()
{
         return “itcast”;
}

返回char类型指针的函数

指向函数的指针

书写格式:

//定义一个指向无形参无返回值函数的指针p
void  (*p) ();
//定义一个指向两个整型形参返回整型值函数的指针m  
int (*m) (int,int);

解读:

1) (*p)是固定写法,代表指针变量p指向的函数

2) 左边的void:表示指针变量p指向的函数没有返回值

3) 右边的():指针变量p指向的函数没有形参

指向函数的指针的调用

//定义一个函数test
void test()
{
}
//定义一个指向test函数的指针
void (*p) ();
//将指针p指向test函数
p=test;
//用指向函数的指针p调用函数test
(*p)();  //第一种调用方式
p();      //第二种调用方式

其他数据类型

1) 全局/局部变量(按作用域划分)

局部变量(没有固定的初始化值

定义:在函数(或代码块)内部定义的变量,包括函数形参

作用域:从定义变量的那一行开始,一直到函数(或代码块)结束

生命周期:从定义变量的那一行开始分配存储空间,函数(或代码块)结束后,就会被收回

全局变量(默认初始值为0

定义:在函数外面定义的变量

作用域:从定义变量的那一行开始,一直到文件结尾(能被后面的所有函数共享)

生命周期:程序一启动就会分配存储空间,程序退出时才被销毁

2) 结构体

结构体:可以由多个不同类型的数据构成

定义结构体类型(并不分配空间)

第一种:只定义结构体类型

struct Person
{
     int age;
     double height;
     char *name;
};

第二种:定义类型的同时定义变量stu

struct Animal
{
     int age;
     char *name;
} dog;

第三种:省略类型名同时定义变量stu定义

struct{
   int age;
   char *name;
} dog;
已有结构体类型,即可定义结构体变量(分配空间)

三种赋值方式

第一种:

struct Person p={20,1.75,"jack"};

第二种:

struct Person p;  //定义结构体person类型的变量p
p.age=23;
p.height=1.75;
p.name="rose";

第三种:

struct Person p={.age=25,.height=1.75,.name="jim"};<span style="color:red;">
</span>

注意:用{}大括号给结构体赋值时,只能用于定义变量同时初始化时

结构体内存管理

1) 结构体分配空间时,内存寻址由小到大依次分配(区别于基本类型和数组)

2) 结构体变量间可以相互赋值

3) 补齐算法

结构体所占用的空间,一定是最大成员变量字节数的倍数

结构体的作用域

自定义的结构体类型变量的作用域与基本数据类型变量的作用域相同,但注意,只定义结构体类型是不分配空间的

结构体数组

用数组存储多个结构体类型的数据,如:struct Person p[3]={{},{},{}};

结构体指针

指向结构体的指针定义

struct Person *p;

利用指针访问结构体的成员

(*p).成员变量

p->成员变量

结构体嵌套

结构体的成员变量可以为其他结构体,但不能是结构体本身,即:不能嵌套自己本身

3) 枚举类型

定义枚举类型:

enum 变量名

{

           常量1,

           常量2,

           常量3,

};

注意:枚举类型定义成员常量时间隔符号为逗号','

//定义枚举season类型
enum Season
{
      spring,
      summer,
      autumn,
      winter
};

Season枚举类型中的常量spring,summer,autumn,winter的本质为:0,1,2,3

定义枚举类型变量

enum 类型名 变量名=常量1/常量2/常量3;

//定义枚举Season类型的变量s
enum Season s=spring;

使用场合

当变量值为固定几个的时候

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值