C语言-3-复杂数据类型

---------- CornerFly真诚期待与您交流! ----------

一、数组


1、定义

元素类型 数组名[元素个数];

比如:int ages[3];

*数组只能存放一种类型的数据,并且是有序的。

2、赋值

1> int ages[3];

age[0] = 19;

age[1] = 20;

age[2] = 29;

2>int a[3] = {10, 9, 6};

*只能在定义数组的同时使用这种方式给数组初始化

3>int ages[5] = {[3] = 11, [4] = 19};

3、遍历

*遍历是指按顺序查看数组的每个元素。可使用循环实现数组的遍历

int age[5] = {29,20,19,28,39};
for(int j = 0; j<5; j++)
{
printf(“age[j] = %d”, j, age[j]);
}

4、使用注意


1> int age[]; 是错误写法,数组定义的时候必须指明元素个数

2>如果想在定义数组的同时进行初始化,元素个数必须为常量不能是变量

5、计算数组长度

int age[] = {29,20,19,28,39};
int count = sizeof(age)/sizeof(int); // count为数组的元素个数

 

6、内存存储细节

数组在内存中是一段连续的存储空间,存储是按照自上而下的顺序存储,越往下地址越高。

7、数组和函数

#include <stdio.h>
void change(int array[])
{
	array[0] = 100;
}
int main()
{
	int ages[3] = {10,19,11};
	change(ages); // 传递的是ages数组的地址
	printf(“ages[0] = %d\n”,ages[0]); // 输出的是100
}

*数组作为函数参数,可以忽略元素个数

*数组作为函数参数,传递的是数组的地址,修改函数参数元素的值,实参数组也会改变。


二、字符串


1、定义

1> 利用数组

 char name[] = "itcast";

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

 * 使用场合:字符串的内容需要经常修改的

2> 利用指针

 char *name = "itcast";

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

* 使用场合:字符串的内容不需要修改,而且这个字符串经常使用

2、strlen

1>strlen函数:计算字符串长度,计算的是字符数,不是字数,计算的字符不包括尾部的\0,一个汉字算作3个字符,从某个地址开始数字符的个数,直到\0为止

2> strlen函数的声明在string.h文件中,用的时候加上#include <string.h>

3、练习:编写一个函数char_contains(char str[],char c),如果字符串str中包含字符c则返回数值1,否则返回数值0

int char_contains(char str[], char c)
{
	// 1. 遍历整个字符串
	for(int j = 0;j <strlen(str);j++)
	{
	// 如果发现某个字符等于参数c,直接返回1,退出函数
	if(str[j] == c)
		{				
                   return 1;	
                }
	return 0;
}

 

三、指针


1、定义及赋值
变量类型 *变量名
*指针变量只能存储地址,指针可以根据地址值访问对应的存储空间,而变量类型限制指针
只能访问当前的变量类型
*指针就是存储变量地址的一个变量
1>先定义再赋值
int a = 10;
int *p;
// 指针变量p指向了变量a
p = &a;
2> 定义的同时赋值
int a = 10;
int *p = &a;
*p = 20;// 把a的值变成20
*指针就一个作用:能够根据一个地址值,访问对应的存储空间。
2、指向函数的指针
1>

void test()
  {
 	printf("调用了test函数\n");
  }
   // (*p)是固定写法,代表指针变量p将来肯定指向函数
   // 左边的void,指针变量p指向的函数没有返回值
   // 右边的():指针变量p指向的函数没有形参
    void (*p)();
    // 指针变量p指向了test函数
    p = test;
    // 利用指针变量间接调用函数
    //(*p)();
    p();
    int sum(int a, int b)
    {
 	return a + b;
    }
    int (*p)(int, int);
    p = sum;
    int c = p(10,11);

 

四、结构体
 

1、 结构体和数组的区别

*结构体可以由不同类型的数据构成

*数组只能由相同类型的数据构成

2. 定义结构体

1>先定义结构体类型,再定义结构体变量

int ages[3] = {10, 10, 13};

// 定义结构体类型
struct Person
{
	int age;
	double height;
	char *name;
};
// 根据结构体类型定义结构体变量
struct Person p = {20, 1.55, "jack"};
p.age = 30;
p.name = "Rose";
printf("age=%d, name=%s, height=%f\n", p.age, p,name, p,height);
 // 以下是错误写法
 struct Person p;
 p = {20, 1.55, "jack"};// 只能在定义的时候对结构体进行初始化
2> 定义结构体类型的同时定义结构体变量
Struct Date
 {
 	int year;
 	int month;
	int day;
 } date;
// 嵌套定义
 struct Student
 {
 	int no; // 学号
	struct Date birthday; // 生日
	struct Date ruxueDate; // 入学日期
 } stu;
 struct Student stu = {1, {2000, 9, 10}, {2012, 9, 10}};
// 输出结构体数据 
printf("year=%d, month=%s, day=%f\n", stu.birthday.year, stu.birthday.month, stu.birthday.dayr);
3>省略结构体类型名,定义结构体变量
 struct Student
 {
	int no; // 学号
 	struct Date birthday; // 生日
	struct Date ruxueDate; // 入学日期
	char *name; // 名称
	double height; // 身高
	int age; // 年龄
 } stu2;

 

3、结构体类型不能重复定义。

4、指向结构体的指针的定义

struct Student *p;
// 指针p指向结构体变量stu
p = &stu;

 

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

1> (*p).成员名称

2> p->成员名称


五、枚举


1、使用场合

当一个变量只允许有几个固定取值时,使用枚举。

2、定义

// 定义枚举类型
 enum Season
 {
 sping,
 summer,
 autumn,
 winter
 };
// 定义枚举变量
 enum Season s = summer;

 

六、预处理指令

1、定义

预处理指令就是在代码翻译成0和1之前执行的指令。包括宏定义、条件编译和文件包含。

2、特点

*预处理指令都是以#开头的。

*预处理的位置是随便写的

*预处理指令的作用域:从编写指令的那一行开始,一直到文件结尾

3、宏定义

*宏名一般用大写或者以k开头,变量名一般用小写 

例:#define COUNT 500;

#define pingfang(a) a*a // 带参数的宏

4、条件编译

#if (a == 10)
	printf(“a是10\n”);
#elif(a == 5)
	printf(“a是5”);
#else
	printf(“a 是其他值”);
#endif

 

5、文件包含

#include <stdio.h>

*<>表示系统自带的文件,””表示自定义的文件

*不允许循环包含,比如a.h包含b.h,b.h又包含a.h

 

七、typedef


1、

// 给int起了个MyInt的名
typedef  int  MyInt;
MyInt c = 20;
2、
// 给指针类型char *起一个新的类型名称String
typedef char * String;
String name = "jack";
3、
// 给指针类型char *起一个新的类型名称String
typedef char * String;
String name = “jack”;

 

八、static和extern

1、函数分类:

*外部函数:定义的函数能被本文件和其他文件访问,

默认情况下所有函数都是外部函数。

不允许有同名的外部函数。

*内部函数:定义的函数只能被本文件访问,其他文件不能访问。

允许不同文件中有同名的内部函数。

2、对函数的作用

*static对函数的作用:声明和定义一个内部函数。

*extern对函数的作用:完整地声明和定义一个外部函数。(extern可以省略)

1>

// 完整地声明一个外部函数
extern void test();
// 完整地定义了一个外部函数
extern void test() // extern可以省略
{
printf(“调用了test函数”);
}
// 完整地声明一个内部函数
2>static void test2() // extern可以省略
{
printf(“调用了test2函数”);
}

 

3、变量分类

可分为全局变量和局部变量。全局变量又可分为2种:

*外部变量:定义的变量能被本文件和其他文件访问。

默认情况下,所有的全局变量(默认情况下都是0)都是外部变量。

*内部变量:定义的变量只能被本文件访问,不能被其他文件访问。

不同文件中的同名内部变量,互不影响。

4、对变量的作用

*extern对变量的作用:声明一个外部变量

*static对变量的作用: 定义了一个内部变量

// 定义了一个内部变量

static int b;

// 声明了一个外部变量

extern int a;

5、static对局部变量的作用

*延长局部变量的声明周期:程序结束的时候,局部变量才会被销毁

*并没有改变局部变量的作用域。

九、递归

设计一个函数,用来计算b的n次方。

int pow2(int b,int n)
{
	if(n <= 0) 
	{		
                return 1;
	}
	return pow2(b,n-1)*b;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值