一、课堂代码
1、值传递、地址传递、值返回、地址返回
#include
#include
#include
/**************值传递*******************/
//普通变量作为函数参数传递是单向的值传递
//将实参的值复制给形参,形参的改变不会影响实参的值
void swap(int m,int n)
{
int temp;
temp = m;
m = n;
n = temp;
printf("m = %d, n = %d\n", m, n); //514 114
}
/***************值传递2*******************/
//主调函数中传递地址,被调函数用指针接收
//被调函数中没有改变指向空间的内容,只改变指向
void fun(int *p,int *q)
{
int *temp;
temp = p;
p = q;
q = temp;
printf("*p = %d, *q = %d\n", *p, *q); //514 114
}
/******************地址传递***********************/
//主调函数中传递地址,被调函数用指针接收
//被调函数中更改指针指向的内容
void gun(int *p,int *q)
{
int *temp;
temp = *p;
*p = *q;
*q = temp;
printf("*p = %d, *q = %d\n", *p, *q); //514 114
}
/********************值返回**********************/
//普通变量通过函数返回值进行返回是单向的值返回
int hun()
{
int value = 666;
return value;
}
/********************地址返回************************/
//需要返回生命周期比较长的变量地址
int *iun()
{
static int value = 999; //静态变量虽然在函数体内定义,但是不占函数的内存空间
//静态局部变量生命周期很长
return &value; //返回静态局部变量的地址
}
/******************主函数**********************/
int main(int argc, const char *argv[])
{
int num = 114;
int key = 514;
//调用swap函数交换两数
swap(num, key);
printf("调用swap后,主函数中num = %d,key = %d\n", num, key); //114 514
//调用fun函数交换两数
fun(&num, &key);
printf("调用fun后,主函数中num = %d,key = %d\n", num, key); //114 514
//调用gun函数交换两数
gun(&num, &key);
printf("调用gun后,主函数中num = %d,key = %d\n", num, key); //514 114
//调用hun函数
//hun() = 2; //error:值返回的函数返回值是临时值,只能作为右值
int ret = hun();
printf("hun() = %d\n",hun()); //666
//调用iun函数
int *ptr = iun(); //地址返回的结果可以作为右值
*iun() = 555; //地址返回的结果可以作为左值,在主调函数中更改了value的值
printf("*iun() = %d\n",*iun()); //555
printf("*ptr = %d\n",*ptr); //555
return 0;
}
2、内存申请
#include
#include
#include
int m; //未初始化的全局变量,在全局区的.bss段
int n = 1; //已初始化的全局变量,在全局区的.data段
static int k; //未初始化的静态变量,在全局区的.bss段
static int l = 2; //已初始化的静态变量,在全局区的.data段
char arr[100] = "hello world"; //arr数组在全局区的.data段,而"hello world"在.ro段
char *p = "hello"; //指针在.data段,而"hello"在.ro段
int main(int argc, const char *argv[])
{
int a; //局部变量在栈区申请,初始值为随机值
double b = 999.0; //局部变量在栈区申请
//printf("&a = %p, &b = %p\n",&a,&b);
static int c; //静态局部变量,在全局区的.bss段申请
static int d = 1; //静态局部变量,在全局区的.data段
char *q = "nihao"; //q在栈区申请的8字节,但"nihao"在全局区的.ro段
char e[100] = "hello"; //数组在栈区申请,但"hello"在全局区的.ro段
int *ptr = (int *)malloc(sizeof(int)); //ptr在栈区,申请的空间在堆区
return 0;
}
3、内存分配与回收(malloc和free的使用)
#include
#include
#include
int main(int argc, const char *argv[])
{
//在堆区申请一个int类型的空间大小
int *p1 = (int *)malloc(4); //申请4字节的大小
printf("*p1 = %d\n",*p1); //随机值
int *p2 = (int *)malloc(sizeof(int)); //申请一个int类型的大小
*p2 = 1; //给堆区空间进行赋值
printf("*p2 = %d\n",*p2); //1
//连续申请5个int类型的大小
int *p3 = (int *)malloc(sizeof(int)*5);
//输出默认值
for(int i=0; i<5; i++)
{
printf("%d\t",p3[i]);
printf("%d\t",*(p3+i));
}
printf("\n");
//释放堆区空间
free(p1);
p1 = NULL; //防止野指针
free(p2);
p2 = NULL;
free(p3);
p3 = NULL;
return 0;
}
4、在堆区申请6个int类型空间存放6名学生的成绩,用函数实现申请空间、输入数据并升序排序后输出
#include
#include
#include
//定义输入函数,ptr表示指向堆区空间的地址,n表示堆区空间元素个数
void input(int *p,int n)
{
int i;
if(NULL != p)
{
//开始进行输入工作
for(i=0; i *(p+j+1)) //大升小降
{
//交换
temp = *(p+j);
*(p+j) = *(p+j+1);
*(p+j+1) = temp;
}
}
}
}
//定义输出函数
void output(int *p,int n)
{
int i;
for(i=0;i
5、类型重定义
#include
#include
#include
typedef unsigned short int uint16; //将无符号短整形重命名为uint16
typedef int * Ptr_i; //将int*类型重命名为Ptr_i
typedef char String[10]; //将char [10]类型重命名为String
int main(int argc, const char *argv[])
{
uint16 num = 520; //等价于unsigned short int num = 520
printf("sizeof num = %ld\n",sizeof(num)); //2
printf("num = %d\n", num); //520
Ptr_i p1 = NULL; //p1是指针变量,等价于int *p1
printf("sizeof p1 = %ld\n",sizeof(p1)); //8
String s1; //定义长度为10的字符数组
strcpy(s1,"hello");
printf("s1 = %s\n",s1); //hello
printf("sizeof s1 = %ld\n",sizeof(s1)); //10
printf("strlen s1 = %ld\n",strlen(s1)); //5
return 0;
}
6、给类型起多个名
#include
#include
#include
typedef int *Ptr_i, int32; //int32是一个int类型的重命名
//Ptr_i是int*类型的重命名
int main(int argc, const char *argv[])
{
int32 num; //num是一个普通变量
Ptr_i p; //p是一个int*类型的变量
printf("sizeof num = %ld\n",sizeof(num)); //4
printf("sizeof p = %ld\n",sizeof(p)); //8
return 0;
}
7、类型重定义与宏定义的区别
#include
#include
#include
/*
#define int32 int //将uint32替换成int
typedef unsigned int uint32; //类型重定义
*/
#define ptr_i int*
typedef int * pptr_i;
int main(int argc, const char *argv[])
{
//int32 num;
//uint32 key;
ptr_i a,b; //a是指针类型,b是普通int类型 等价于int *a, b;
pptr_i m,n; //m和n都是指针类型
printf("sizeof a = %ld\n",sizeof(a)); //8
printf("sizeof b = %ld\n",sizeof(b)); //4
printf("sizeof m = %ld\n",sizeof(m)); //8
printf("sizeof n = %ld\n",sizeof(n)); //8
return 0;
}
8、结构体变量的定义及初始化,与指针访问成员
#include
#include
#include
//声明一个英雄结构体类型
struct Hero
{
char name[20]; //姓名
int Hp; //血量
double speed; //基础位移
int kill; //人头数
}h3 = {"盖伦",3500,500,5};
//练习:定义一个商品类型
struct Goods
{
char name[20]; //名称
char position[30]; //产地
double price; //单价
double weight; //重量
};
//法2 :
/*struct //无名结构体
{
char name[40];
char position[40];
double price;
double weight;
}g2 = {"奶粉","China",350,1000}; //后期该结构体就不能再定义变量了,但是h1可以被重新赋值
*/
int main(int argc, const char *argv[])
{
//使用英雄类型定义一个英雄变量
struct Hero h1 = {"亚索",650,350,0}; //定义一个英雄变量h1
//定义英雄变量,指定某个成员进行赋值
struct Hero h2 = {.Hp = 2000,.speed = 1000}; //定义h2,指定属性初始化,没有初始化的是随机值
//输出英雄变量h1中的所有内容
printf("h1.name = %s\n",h1.name);
printf("h1.Hp = %d\n",h1.Hp);
printf("h1.speed = %lf\n",h1.speed);
printf("h1.kill = %d\n",h1.kill);
//在堆区申请一个英雄类型,完成初始化并输出相应的属性
struct Hero *ptr = (struct Hero*)malloc(sizeof(struct Hero));
//给英雄名字赋值
strcpy(ptr->name,"亚瑟"); //给姓名赋值
ptr->Hp = 3000; //给hp属性赋值
ptr->speed = 350;
ptr->kill = 3;
//输出英雄指针指向堆区空间中的内容
printf("英雄信息为:%s %d %.2lf %d\n",ptr->name,ptr->Hp,ptr->speed,ptr->kill);
printf("***************************************************\n");
//使用商品结构体定义,不初始化,使用scanf给每个变量赋值再输出
struct Goods g1;
printf("请输入商品的名称:");
scanf("%s",g1.name);
printf("请输入商品的产地:");
scanf("%s",g1.position);
printf("请输入商品的单价:");
scanf("%lf",&g1.price);
printf("请输入商品的重量:");
scanf("%lf",&g1.weight);
//输出信息
printf("\n");
printf("商品信息:%s %s %.2lf %.2lf\n",g1.name,g1.position,g1.price,g1.weight);
return 0;
}
思维导图