2019/8/25 C语言回顾(8)

一、函数
函数是功能性代码的集合,通常情况下函数需要返回值
 
1、函数声明
 
返回值类型 函数名(形参);
不写声明会有警告,或者可以将函数定义拿到main函数上方
 
2、函数调用
函数名(实参);
 
3、函数定
{
c语句块;
return ;
}
 
形参:一定是变量,用来接收实参的值
实参:可以是变量,也可以是常量
 
二、函数传参
1、赋值传参
把值拷贝一份,对拷贝的值修改不会影响原来的值
 
2、地址传参
将某一个数据的地址传参,通过地址修改数据会改变原来的数据
一般情况下不要将全局变量作为传参
 
【1】数组传参
  • 一维数组传参
int a[3] = {1,2,3};
 
1、一种形式
int fun(int a[3])
{
return 0;
}
 
fun(a);
2、第二种形式
int fun(int *p)
{
return 0;
}
 
  • 二维数组传参
int a[2][3] = {{1,2,3},{4,5,6}};
fun(a);
 
int fun(int a[2][3]) // int (*p)[3]
 
int fun(int (*p)[3])
 
  • 指针数组传参
int *a[3] ={};
fun(a);
 
int fun(int *a[])
 
int fun(int **p)
 
【2】返回值为指针的函数
注意:返回的地址不可以是一个非静态局部变量的地址,当函数调用结束之后,该地址里面的内容随时会被改变
 
【3】
函数的类型
int fun(int a,char b)
||
int (int,char)   或者 int (int a,char b)
 
  • 函数名是函数的入口地址
函数指针
int (int ,char) *p = fun;//错误
int (*p)(int ,char);
 
atoi
#include <stdlib.h>
int atoi(const char *nptr);
功能:将字符串转化为整型数据
参数:字符串首地址
返回值:正常情况(字符串由'0' ~ '9'组成)返回被转化的整形值,不符合要求则返回0;
malloc
#include <stdlib.h>
void *malloc(size_t size);
功能:从堆区申请空间
参数:申请的空间大小
返回值:返回值申请的堆区空间的首地址
int *p;
p = (int *)malloc(sizeof(int) * 5);
 
#include <stdio.h>
#include <stdlib.h>
#if 0
malloc
头文件:#include <stdlib.h>
void * malloc(size_t size)
功能:在堆区空间上开辟size大小的一片连续的空间,且返回该连续空间的首地址
参数:size_t == unsigned int 需要开辟空间的大小
返回值:返回该空间的首地址
#endif
 
int main(int argc, const char *argv[])
{
int *p ;
p = (int *)malloc(sizeof(int) * 10);
 
int i;
for(i = 0; i < 10; i++)
{
*(p+i) = i * 10;
}
 
for(i = 0; i < 10; i++)
{
printf("%d\n", *(p+i));
}
 
#if 0
void free (void *ptr)
功能:释放以 void * ptr为首地址的一片连续空间
#endif
free(p);
return 0;
}
 
 
 
void free(void *p)
功能:释放堆区空间
参数:地址
free(p);
 
 
三、结构体
【1】一般形式
struct student//标签名(仅仅是结构体的名字)
{
char name[128];//填充结构体成员
int id;
int age;
float score;
};//注意末尾有;
结构体类型:struct  + 标签名
struct student a = {"123", 1, 18, 88.8};//结构体变量定义:结构体类型  变量名
 
//struct student == int (数据类型名)
//student :结构体的名字
 
int main(int argc, const char *argv[])
{
struct student a = {"陈力", 1, 18, 88.8};//结构体变量定义:结构体类型  变量名
 
//结构体变量的初始化,并且需要一一对应成员赋值
 
printf("name:%s id:%d age:%d score:%.1f\n", a.name, a.id, a.age, a.score);
 
//结构体变量应用内部成员时需要通过:结构体变量名.结构体成员名
 
return 0;
}
 
【2】typedef 给某一个数据类型起别名
typedef struct 标签名
{
。。。
}A;
 
typedef int A
define A int
define是完整的字符串替换,不可以给复杂数据类型进行宏替换,typedef可以给复杂类型起别名,但要注意别名的写法
 
结构体初始化
只能在定义的同时全部赋值,后期赋值需要一个一个操作
 
如何引用结构体成员
结构体变量.结构体成员
 
结构体大小
struct student
{
char name[16];
int age;
float high;
};
 
内存对齐
1、4字节对齐
2、结构体每一个成员的起始位置必须是自身大小的整数倍
3、结构体总大小必须是最大成员(不包含复杂类型)的整数倍
4、double在这里视为两个4字节
 
struct student
{
int a;
char b[0];
};(大小为四个字节,char b[0] 零元数组)
#include <stdio.h>
#if 0
#define  A  int
#define  B  int [6]
#define 标识符 被替换的目标
注:字符串的整体替换,不适合替换数据类型
#endif
 
 
#if 0
格式:typedef   已知或已经存在的数据类型  别名;
功能:给已知或者已经存在的数据类型起别名
注:typedef末尾有分号
#endif
 
typedef int  A;
typedef int B[6];
typedef int (*C)[6];
typedef int (*D)(int,int);
 
int fun(int m, int n)
{
return m+n;
}
 
int main(int argc, const char *argv[])
{
A a  = 10;
B b = {1,2,3,4,5,6};
C P = &b;
D q = fun;
int m = 10, n = 15;
q(m,n);
 
return 0;
}
 
【3】结构体指针
stu_t s; //结构体变量 s
stu_t *p = &s;   //结构体指针 p
结构体指针引用结构体成员的方式:
1、通过取值再用.的方式
2、指针直接指向结构体成员(->)
 
四、共用体
union a
{
char a;
int b;
};
//union:共用体,里面成员共用同一片空间,空间大小向最大的数据类型看齐
//所以只能同时使用其中一个成员
//注:共用体union使用时需要先将空间初始化(用大的数据类型赋予0值做初始化)
int main(int argc, const char *argv[])
{
union a stu;
stu.b = 0;
stu.a = 10;
printf("%d\n", sizeof(union a));
printf("%d\n", stu.a);
printf("%d\n", stu.b);
return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/epll/p/11409227.html