当前位置:网站首页>C学习完结
C学习完结
2022-04-23 19:23:00 【L-xykeen】
C学习
小知识:
goto: 跳到指定位置
#include <stdio.h>
int main()
{
int a;
scanf_s("%d", &a);
if (a > 0) {
printf("no\n");
}
else
{
printf("yes\n");
goto A;//跳到 A 后面语句
}
A: printf("%d", a);
return 0;
}
强制转换:(填类型)10/3
itoa用法:
itoa(res, str, 10); //数字转为字符串(整型,字符串,进制)
● ltoa():将长整型值转换为字符串。
● ultoa():将无符号长整型值转换为字符串。
● gcvt():将浮点型数转换为字符串,取四舍五入。
● ecvt():将双精度浮点型值转换为字符串,转换结果中不包含十进制小数点。
● fcvt():指定位数为转换精度,其余同ecvt()。
-
‘\0’ :是字符串的结尾符
length = sizeof(array)/sizeof(array[0]); :求 int 数组长度
scanf(“%[ ^\n]”, str); :(非回车)获取字符集,遇到 回车时,停止获取
无前缀方式:
printf(“%o”,num) //无前缀o的8进制数
printf(“%d”,num) //无前缀0d的10进制数
printf(“%x”,num) //无前缀0x的小写16进制数
printf(“%X”,num) //无前缀0X的大写16进制数
有前缀方式:
printf(“%#o”,num) //有前缀o的8进制数
printf(“%#d”,num) //有前缀0d的10进制数
printf(“%#x”,num) //有前缀0x的小写16进制数
printf(“%#X”,num) //有前缀0X的大写16进制数
字符串
-
sizeof() 包含\0 strlen() 不包含\0
-
strcpy(str3, str1); str1 拷贝到 str3
-
strncpy(str3, str1, n); str3[n] = “\0”; n 是拷贝限制数,最后要加结束符,防止出现异常
-
strcat(str1, str2); 连接 str1 与 str2
-
strcmp(str1, str2) str1与str2 相同,返回0,否则1
指针
间接访问:
char a;
char *p = &a;
printf("请输入一个字符:");
scanf("%c", &a);
printf("%c\n", *p); //输出变量 a
指向数组的指针:(数组名是标记数组第一个元素的位置)(p+1 是地址(单个数组元素)+1)
char a[] = "abcd";
char *p = a;
printf("%c %c %c\n", *p, *(p+1), *(p+2));//输出 a b c
指针数组
例如: int *p[n]
:指针数组是一个数组,每个数组元素存放一个指针变量
int main(int argc, char *argv[]) {
char *p[3] = {
"李锦彪",
"黄欣宇",
"锦欣宇"
};
int i;
for(i = 0; i<3;i++){
printf("%s\n", p[i]);//加 *p 是取字符,不加取字符串
}
return 0;
}
数组指针
例如: int (*p)[5];
:数组指针是一个指针,它指向的是一个数组
int main(int argc, char *argv[]) {
int p[3] = {
1,2,3};
int *p1 = p;//指针p1 指向p的第一个元素地址
int i;
for(i = 0; i<3;i++){
printf("%d\n", *(p1+i));
}
return 0;
}
int main(int argc, char *argv[]) {
int p[3] = {
1,2,3};
int (*p1)[3] = &p;//取数组 p 的地址给 数组指针p1
int i;
for(i = 0; i<3;i++){
printf("%d\n", *(*p1+i));
}
return 0;
}
二维数组和指针
数组名是第一个元素的地址
例如: 二维数组arry[m] [n] , *arry 指向二维数组第一个元素地址
*(arry+1) 指向二维数组的第二行第一个元素的地址
int main(int argc, char *argv[]) {
int p[3][4] = {
0};
int i,j,k=0;
for(i = 0; i<3;i++){
for(j = 0; j<4;j++){
p[i][j] = k++;
}
}
printf("*(p+1) : %p\n",*(p+1));
printf("p[1] : %p\n", p[1]);
printf("&p[1][0]: %p\n", &p[1][0]);
printf("*(*(p+1)+3): %d\n", *(*(p+1)+3));
printf("p[1][3]: %d\n", p[1][3]);
return 0;
//结论:*(p+i) == p[i]
// *(*(p+i)+j) == p[i][j]
// *(*(*(p+i)+j)+k) == p[i][j][k]
}
二维数组与指针 ( 一个 * 是取地址, ** 解引用 )
int main(int argc, char *argv[]) {
int temp[2][3] = {
{
1,2,3},{
4,5,6}};
int (*p)[3] = temp;
//输出temp[1][0]
printf("**(p+1) : %d\n",**(p+1));
printf("**(temp+1) : %d\n", **(temp+1));
printf("temp[1][0] : %d\n", temp[1][0]);
//输出temp[1][2]
printf("*(*(p+1)+2) : %d\n",*(*(p+1)+2));
printf("*(*(temp+1)+2) : %d\n", *(*(temp+1)+2));
printf("temp[1][2] : %d\n", temp[1][2]);
return 0;
}
/* **(p+1) : 4 **(temp+1) : 4 temp[1][0] : 4 *(*(p+1)+2) : 6 *(*(temp+1)+2) : 6 temp[1][2] : 6 */
void 指针
:称之为通用指针,就是可以指向任意类型的数据。也就是说,任何类型的指针都可以赋值给void指针
int main(int argc, char *argv[]) {
int num = 1024;
int *pi = #
char *ps = "lijinbiao";
void *pv;
pv = pi;
printf("pi:%p, pv:%p\n",pi,pv);
printf("pv:%d\n",*(int *)pv); //使用void指针要强制类型转换
pv = ps;
printf("ps:%p, pv:%p\n",ps,pv);
printf("pv:%s\n",(char *)pv);
return 0;
}
/* pi:000000000062FE04, pv:000000000062FE04 pv:1024 ps:0000000000404000, pv:0000000000404000 pv:lijinbiao */
null指针
建议:当你还不清楚要将指针初始化为什么地址时,请将它初始化为null;在对制作进行解引用时,先检查该指针是否为null。这种策略可以为你今后编写大型程序节省大量的调试时间
指向指针的指针
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AiReqK4l-1650532107500)(C:\Users\15751083927\AppData\Roaming\Typora\typora-user-images\image-20220224195144476.png)]
int main(int argc, char *argv[]) {
char n[] = "abc";
char (*p)[] = &n;
char (**pp)[] = &p;
printf("%s\n",*p);
printf("%s\n",**pp);
return 0;
}
/* abc abc
指针数组和指向指针的指针
好处:
避免重复分配内存
只需要进行一处修改
int main(int argc, char *argv[]) {
char *cbook[] = {
//指针数组
"李锦彪",
"黄欣宇",
"锦欣宇"};
char **bybook;
char **lilove[3];
bybook = &cbook[2];
lilove[0] = &cbook[0];
lilove[1] = &cbook[1];
lilove[2] = &cbook[2];
printf("bybook:%s\n",*bybook);
printf("lilove:\n");
int i;
for(i=0;i<3;i++){
printf("%s\n",*lilove[i]);
}
return 0;
}
/*输出结果: bybook:锦欣宇 lilove: 李锦彪 黄欣宇 锦欣宇
数组指针和二维指针
int main(int argc, char *argv[]) {
int arry[3][4] = {
1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4] = arry;
int i,j;
for(i=0;i<3;i++){
for(j=0;j<4;j++){
printf("%4d", *(*(p+i)+j));
}
printf("\n");
}
return 0;
}
/* 1 2 3 4 5 6 7 8 9 10 11 12
常量和指针
使用const 关键字修饰,使变量变为常量,即不可修改
const int price = 520;
const char str = "asdfj";
函数
void print_c(); //函数声明
void print_c(){
//函数定义
printf(" ****** \n");
printf("** **\n");
printf("** \n");
printf("** \n");
printf("** **\n");
printf(" ****** \n");
}
int main(int argc, char *argv[]) {
print_c(); //函数调用
return 0;
}
参数和指针
数组函数要有下标
#include <stdio.h>
#include <stdarg.h>
int sum(int n, ...);// n 是参数个数 ... 表示不确定几个参数
int sum(int n, ...){
int i, sum=0;
va_list vap; // 定义参数列表
va_start(vap, n); //开始 输入值
for(i=0;i<n;i++){
sum += va_arg(vap, int); // va_arg 获取每个参数的值(类型(int,char))
}
va_end(vap); //关闭列表
return sum;
}
int main(int argc, char *argv[]) {
int result;
result = sum(1,2,3,3);
printf("result = %d\n", result);
result = sum(10,2,3,4,5,6,7,8,99);
printf("result1 = %d\n", result);
return 0;
}
指针函数 函数指针
指针函数 :类型 *函数名 (参数)
不要返回局部变量的指针
#include <stdio.h>
#include <stdarg.h>
char *getWord(char c);
char *getWord(char c){
switch(c){
case 'A': return "Apple"; // 返回的是字符串的第一个地址
case 'B': return "Banana";
case 'C': return "Cat";
case 'D': return "Dog";
default: return"None";
}
}
int main(int argc, char *argv[]) {
char input;
printf("请输入一个字母:");
scanf("%c", &input);
printf("%s\n", getWord(input));
return 0;
}
/* 不能返回局部变量 如下: char *getWord(char c){ char str1[] = "Apple"; char str2[] = "Banana"; char str3[] = "Cat"; char str4[] = "Dog"; char str5[] = "None"; switch(c){ case 'A': return str1; case 'B': return str2; case 'C': return str3; case 'D': return str4; default: return str5; } }
函数指针: 类型名 (*函数名)(参数)
int square(int);
int square(int num){
return num*num;
}
int main(int argc, char *argv[]) {
int num;
int(*fp)(int); //函数指针
printf("请输入一个整数:");
scanf("%d", &num);
fp = square;
printf("%d * %d = %d", num, num,(*fp)(num));
return 0;
}
int add(int, int);
int sub(int, int);
int calc(int (*fp)(int, int), int, int); //函数指针作为参数
int add(int a, int b){
return a+b;
}
int sub(int a, int b){
return a-b;
}
int calc(int (*fp)(int, int), int a, int b){
//int (*fp)(int, int) 函数指针
return (*fp)(a, b);
}
int main(int argc, char *argv[]) {
printf("3 + 5 = %d\n", calc(add, 3, 5));
printf("3 - 5 = %d\n", calc(sub, 3, 5));
return 0;
}
#include <stdio.h>
int add(int, int);
int sub(int, int);
int calc(int (*fp)(int, int), int, int);
int (*select(char))(int, int);
int add(int a, int b){
return a+b;
}
int sub(int a, int b){
return a-b;
}
int calc(int (*fp)(int, int), int a, int b){
//int (*fp)(int, int) 函数指针
return (*fp)(a, b);
}
int (*select(char op))(int, int){
switch(op){
case '+' : return add;
case '-' : return sub;
}
}
int main(int argc, char *argv[]) {
int a,b;
char op;
int (*fp)(int, int);
printf("请输入一个式子:");
scanf("%d%c%d", &a, &op, &b);
fp = select(op);
printf("%d %c %d = %d\n", a, op, b, (calc(fp, a, b)));
return 0;
}
局部变量 全局变量
不要大量使用全局变量
// extern 关键字 告诉编译器,这个变量我在后面定义了,别急着报错
#include <stdio.h>
void func();
void func(){
extern count; // extern 关键字 告诉编译器,这个变量我在后面定义了,别急着报错
count++;
}
int count = 0;
int main(int argc, char *argv[]) {
func();
printf("%d\n", count);
return 0;
}
作用域和链接属性
代码块作用域
int main(void) {
int i =100; // i1
{
int i = 110; // i2
{
int i = 120; //i3
printf("i = %d\n", i); // i = 120
}
// i = 110
{
int i = 130; //i4
printf("i = %d\n", i); // i = 130
}
printf("i = %d\n", i); // i = 110
}
printf("i = %d\n", i); // i = 100
return 0;
}
原型作用域
void func(int a, int b, int c);
函数作用域
函数作用域 只适用于goto语句的标签,作用将goto语句的标签限制在同一个函数内部,以防止出现重名标签。(不建议使用goto)
链接属性
external(外部的): 多个文件中声明的同名标识符表示同一个实体
internal(内部的):单个文件中声明的同名标识符表示同一个实体
none(无) :声明的同名标识符被当作独立不同的实体
只有具备文件作用域的标识符才能拥有external或internal的链接属性,其它作用域的标识符都是none属性
static :内部使用,可以保护全局变量
生存期和储存类型
静态存储期
具有文件作用域的变量属于静态存储期,函数也属于静态存储期。属于静态存储期的变量在程序执行期间将一直占据储存空间,直到程序关闭才释放
动态存储期
具有代码块作用域的变量一般情况下属于自动存储期。属于自动存储期的变量在代码块结束时将自动释放存储空间。
存储类型
auto
在代码块中声明的变量默认的存储类型就是自动变,使用关键字auto来描述
// 用auto提示覆盖前面的 i
int i;
int main(void){
auto int i;
return 0;
}
register(寄存器变量)
将一个变量声明为寄存器变量,那么该变量就有可能被存放于CPU的寄存器中。
static(静态局部变量)
//有static
void func();
void func(){
static int count = 0;
printf("ciount = %d\n", count);
count++;
}
int main(void){
int i;
for(i = 0; i< 10; i++){
func();
}
return 0;
}
/* ciount = 0 ciount = 1 ciount = 2 ciount = 3 ciount = 4 ciount = 5 ciount = 6 ciount = 7 ciount = 8 ciount = 9 */
//没有static
void func();
void func(){
int count = 0;
printf("ciount = %d\n", count);
count++;
}
int main(void){
int i;
for(i = 0; i< 10; i++){
func();
}
return 0;
}
/* ciount = 0 ciount = 0 ciount = 0 ciount = 0 ciount = 0 ciount = 0 ciount = 0 ciount = 0 ciount = 0 ciount = 0
extern
告诉编译器在其他地方定义了
typedef
为数据类型定义一个别名
递归
#include <stdio.h>
long fact(int num);
long fact(int num){
long result;
if(num>0){
result = num * fact(num-1);
}
else
{
result = 1;
}
return result;
}
int main(void) {
int num;
printf("请输入:");
scanf("%d",&num);
printf("%d\n", fact(num));
return 0;
}
汉诺塔
#include <stdio.h>
void fact(int n, char x, char y, char z);
void fact(int n, char x, char y, char z){
if(n == 1){
printf("%c --> %c\n", x, z);
}
else
{
fact(n-1, x, z, y);
printf("%c --> %c\n", x, z);
fact(n-1, y, x, z);
}
}
int main(void) {
int n;
printf("请输入汉诺塔层数:");
scanf("%d",&n);
fact(n, 'X', 'Y','Z');
return 0;
}
快速排序
分治法
#include <stdio.h>
void quick_sort(int array[], int left, int right);
void quick_sort(int array[], int left, int right){
int i = left, j = right;
int temp;
int pivot; // 基准点
pivot = array[(left + right) / 2];
while(i <= j){
//与基准点的大小对比,决定排序方式
//从左到右找到大于等于基准点的元素
while(array[i] > pivot){
i++;
}
//从右到左找到小于等于基准点的元素
while(array[j] < pivot){
j--;
}
//如果i <= j,则互换
if(i <= j){
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
}
if(left < j){
quick_sort(array, left, j);
}
if(i < right){
quick_sort(array, i, right);
}
}
int main() {
int array[] = {11,22,5,8,9,465,45};
int i, length;
length = sizeof(array) / sizeof(array[0]); // 获得数组长度
quick_sort(array, 0, length-1);
printf("排序后的结果是:");
for ( i = 0; i < length; i++) {
printf("%d ", array[i]);
}
return 0;
}
动态内存
malloc(申请动态内存空间)
函数原型:
void *malloc(size_t size);
malloc函数向系统申请分配size个字节的内存空间,并返回一个指向这块空间的指针。
#include <stdio.h>
#include <malloc.h>
int main() {
int *ptr;
ptr = (int *)malloc(sizeof(int));
if(ptr == NULL){
printf("分配内存失败!\n");
exit(1);
}
printf("请输入一个整数:");
scanf("%d", ptr);
printf("你输入的数是:%d\n", *ptr);
return 0;
}
还可以申请一块任意内存的空间:
void arrmalloc(){
int *ptr = NULL;
int num;
printf("请输入带录入整数的个数:");
scanf("%d", &num);
ptr = (int *)malloc(num * sizeof(int));
for (int i = 0; i < num; i++) {
printf("请录入第 %d 个整数:", i+1);
scanf("%d", &ptr[i]);
}
printf("你录入的整数是:");
for (int i = 0; i < num; i++) {
printf("%d ", ptr[i]);
}
putchar('\n');
free(ptr);//用完注释掉
}
初始化内存空间 在 <string.h> 里
memset :使用一个常量字节填充内存空间
memcpy :拷贝内存空间
memmove :拷贝内存空间
memcmp :比较内存空间
memchr :在内存空间中搜索一个字符
void memm(){
int *ptr = NULL;
ptr = (int *)malloc(N * sizeof(int));
if(ptr == NULL){
exit(1);
}
memset(ptr, 0, N * sizeof(int));
for (int i = 0; i < N; i++) {
printf("%d ", ptr[i]);
}
putchar('\n');
free(ptr);
}
free(释放动态内存空间)
函数原型:
void free(void *ptr);
释放ptr参数指向的内存空间
#include <stdio.h>
#include <malloc.h>
void maloc();
void maloc(){
int *ptr;
int num = 123;
ptr = (int *)malloc(sizeof(int));
if(ptr == NULL){
printf("分配内存失败!\n");
exit(1);
}
printf("请输入一个整数:");
scanf("%d", ptr);
printf("你输入的数是:%d\n", *ptr);
//内存泄漏, 没有及时释放
ptr = #
printf("你输入的数是:%d\n", *ptr);
free(ptr); //释放空间
}
int main() {
maloc();
return 0;
}
void callocs(){
int *ptr1 = NULL;
int *ptr2 = NULL;
//第一次申请得申请空间
ptr1 = (int *) malloc(20 * sizeof(int));
//进行若干次操作后发现ptr1申请的内存空间不够用
//第二次申请内存空间
ptr2 = (int *) malloc(20 * sizeof(int));
//将prt1 拷贝到ptr2中
memcpy(ptr2, ptr1, 10);
free(ptr1);
//对ptr2申请的内存空间进行若干操作
free(ptr2);
}
calloc(申请并初始化一系列内存空间)
函数原型:
void *calloc(zise_t nmemb, size_t size);
该函数在内存中动态的申请nmemb个长度为size的连续内存空间(即申请的总空间尺寸为 nmemb * size),这些内存空间全部被初始化为 0。
realloc(重新分配内存空间)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XKsU0PoM-1650532107502)(C:\Users\15751083927\AppData\Roaming\Typora\typora-user-images\image-20220302171057450.png)]
void reallocs(){
int num;
int count = 0;
int *ptr = NULL; //注意必须初始化为NULL
do{
printf("请输入一个整数(输入-1表示结束):");
scanf("%d", &num);
count++;
ptr = (int *) realloc(ptr, count * sizeof(int));
if(ptr == NULL){
exit(1);
}
ptr[count-1] = num;
}while(num != -1);
printf("输入的整数分别是:");
for (int i = 0; i < count; i++) {
printf("%d ",ptr[i]);
}
free(ptr);
}
宏定义
#include <stdio.h>
#define MAX(x, y) (((x) > (y)) ? (x):(y))
int main() {
int x,y;
scanf("%d %d", &x,&y);
printf("%d\n", MAX(x, y));
return 0;
}
结构体
struct 结构体名称{
结构体成员
。。。。
。。。
};
#include <stdio.h>
struct Book{
//定义一个结构体
char title[128];
char author[40];
float price;
unsigned int date;
char publisher[40];
}/* book 在这定义是全局变量*/;
int main() {
struct Book book; //在这定义是局部变量
printf("请输入书名:");
scanf_s("%s", book.title); //使用 . 获取成员
printf("请输入作者:");
scanf_s("%s", book.author);
printf("请输入售价:");
scanf_s("%f", &book.price);
printf("请输入出版日期:");
scanf_s("%d", &book.date);
printf("请输入出版社:");
scanf_s("%s", book.publisher);
printf("数据录入完毕!");
printf("书名:%s\n", book.title);
printf("作者:%s\n", book.author);
printf("售价:%f\n", book.price);
printf("日期:%d\n", book.date);
printf("出版社:%s\n", book.publisher);
return 0;
}
**嵌入结构体: **
#include <stdio.h>
struct Date{
int year;
int month;
int day;
};
struct Book{
//定义一个结构体
char title[128];
char author[40];
float price;
struct Date date;//嵌入一个结构体
char publisher[40];
}/* book 在这定义是全局变量*/
book = {
"李锦彪",
"黄欣宇",
999,
{
2020, 7, 11},
"徐州"
};
int main() {
//struct Book book; //在这定义是局部变量
printf("书名:%s\n", book.title);
printf("作者:%s\n", book.author);
printf("售价:%.2f\n", book.price);
//访问到哪,要去到最底层
printf("日期:%d-%d-%d\n", book.date.year, book.date.month, book.date.day);
printf("出版社:%s\n", book.publisher);
return 0;
}
结构体指针
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P9JOTeHv-1650532107503)(C:\Users\15751083927\AppData\Roaming\Typora\typora-user-images\image-20220303165313657.png)]
#include <stdio.h>
struct Date{
int year;
int month;
int day;
};
struct Book{
//定义一个结构体
char title[128];
char author[40];
float price;
struct Date date;//嵌入一个结构体
char publisher[40];
}/* book 在这定义是全局变量*/
book = {
"李锦彪",
"黄欣宇",
999,
{
2020, 7, 11},
"徐州"
};
int main() {
//struct Book book; //在这定义是局部变量
struct Book *pt;
pt = &book;
printf("书名:%s\n", pt->title); //解引用 指针 -> 变量名
printf("作者:%s\n", pt->author);
printf("售价:%.2f\n", (*pt).price); // 解引用 (*指针).变量名
//访问到哪,要去到最底层
printf("日期:%d-%d-%d\n", (*pt).date.year, (*pt).date.month, (*pt).date.day);
printf("出版社:%s\n", (*pt).publisher);
return 0;
}
传递结构体变量
#include "stdio.h"
struct Date{
int year;
int month;
int day;
};
struct Book{
char title[128];
char author[40];
float price;
struct Date date;
char publisher[40];
};
void getInput(struct Book *book);
void printbook(struct Book *book);
void getInput(struct Book *book){
printf("请输入书名:");
scanf("%s", book->title);
printf("请输入作者:");
scanf("%s", book->author);
printf("请输入售价:");
scanf("%f", &book->price);
printf("请输入出版日期:");
scanf("%d-%d-%d", &book->date.year, &book->date.month, &book->date.day);
printf("请输入出版社:");
scanf("%s", book->publisher);
}
void printbook(struct Book *book){
printf("书名:%s\n", book->title);
printf("作者:%s\n", book->author);
printf("价钱:%.2f\n", book->price);
printf("出版日期:%d-%d-%d\n", book->date.year, book->date.month, book->date.day);
printf("出版社:%s\n", book->publisher);
}
int main(void){
struct Book b1,b2;
printf("请录入第一本书的信息.。。\n");
getInput(&b1);
printf("\n");
printf("请输入第二本书的信息。。。\n");
getInput(&b2);
printf("\n\n录入完毕,现在开始打印验证。。。\n\n");
printf("打印第一本书的信息\n");
printbook(&b1);
printf("\n\n打印第二本书的信息\n");
printbook(&b2);
return 0;
}
动态申请结构体
#include <malloc.h>
#include "stdio.h"
#include "stdlib.h"
struct Date{
int year;
int month;
int day;
};
struct Book{
char title[128];
char author[40];
float price;
struct Date date;
char publisher[40];
};
void getInput(struct Book *book);
void printbook(struct Book *book);
void getInput(struct Book *book){
printf("请输入书名:");
scanf("%s", book->title);
printf("请输入作者:");
scanf("%s", book->author);
printf("请输入售价:");
scanf("%f", &book->price);
printf("请输入出版日期:");
scanf("%d-%d-%d", &book->date.year, &book->date.month, &book->date.day);
printf("请输入出版社:");
scanf("%s", book->publisher);
}
void printbook(struct Book *book){
printf("书名:%s\n", book->title);
printf("作者:%s\n", book->author);
printf("价钱:%.2f\n", book->price);
printf("出版日期:%d-%d-%d\n", book->date.year, book->date.month, book->date.day);
printf("出版社:%s\n", book->publisher);
}
int main(void){
struct Book *b1, *b2;
// 动态申请结构体
b1 = (struct Book *)malloc(sizeof(struct Book));
b2 = (struct Book *)malloc(sizeof(struct Book));
if(b1 == NULL || b2 == NULL){
printf("内存分配失败");
exit(1);
}
printf("请录入第一本书的信息.。。\n");
getInput(b1);
printf("\n");
printf("请输入第二本书的信息。。。\n");
getInput(b2);
printf("\n\n录入完毕,现在开始打印验证。。。\n\n");
printf("打印第一本书的信息\n");
printbook(b1);
printf("\n\n打印第二本书的信息\n");
printbook(b2);
//有申请就有释放
free(b1);
free(b2);
}
单链表
头插法
#include <malloc.h>
#include "stdio.h"
struct Book{
//信息域
char title[128];
char author[40];
//指针域
struct Book *next;
};
void getInput(struct Book *book){
printf("请输入书名:");
scanf("%s", book->title);
printf("请输入作者:");
scanf("%s", book->author);
}
//当我们需要在函数内部申请内存并通过变量传出时。往往使用二级指针
void addBook(struct Book **head){
//二级指针,为了让head原本指向的NULL,指向别处
struct Book *book, *temp;
//申请一个新的节点
book = (struct Book *)malloc(sizeof(struct Book));
if(book == NULL){
printf("失败");
exit(1);
}
//获取输入
getInput(book);
//判断是否为空的单链表
if(*head != NULL){
temp = *head; //原先 head 指向的地址 存在temp里
*head = book; //head 指向book
book->next = temp;//book 指向 刚才head 存在temp里的地址
}else{
*head = book; //head 指向新的节点
book->next = NULL; //节点指向 NULL
}
}
void printlibrary(struct Book *library){
struct Book *book;
int count = 1;
book = library;
while(book != NULL){
printf("Book%d: \n", count);
printf("书名:%s\n", book->title);
printf("作者:%s\n", book->author);
book = book->next;
count++;
}
}
void release(struct Book *head){
while (head != NULL){
head = head->next;
free(head);
}
}
int main(void){
//头节点保存下个信息域的地址
struct Book *head = NULL; //指向第一个节点的指针变量;指向head里存的东西
int ch;
while(1){
printf("请问是否输入(Y/N):");
do{
ch = getchar();
} while (ch != 'Y' && ch != 'N');
if(ch == 'Y'){
//相当于传入指向head的指针
addBook(&head);//传递head的地址
}else{
break;
}
}
printf("请问书否要打印图书信息(Y/N):");
do{
ch = getchar();
} while (ch != 'Y' && ch != 'N');
if(ch == 'Y'){
printlibrary(head);
}
release(head);
return 0;
}
链表
#include "stdio.h"
#include "stdlib.h"
typedef struct node{
int value[2];
struct node *next; // 定义头指针
}Node;
typedef struct list{
Node *head;
Node *tail;
}List;
void add(List *pList, int a, int b);
void print(List *plist);
int main(void){
int n, m, a, b;
List list;
list.head = list.tail = NULL;
scanf("%d %d", &n, &m);
for (int i = 0; i < n + m; ++i) {
scanf("%d %d", &a, &b);
add(&list, a, b); //调用函数增加链表内容,传 list 的指针
}
//输出
print(&list);
//搜索
Node *p;
printf("请输入要查找的数:");
scanf("%d", &n);
int temp = 0;
for (p = list.head;p;p=p->next){
if (p->value[0] == n){
temp = 1;
printf("查找到了\n");
break;
}
}
if (temp == 0){
printf("没有查找到\n");
}
//删除
Node *q;
printf("请输入要删除的数:");
scanf("%d", &n);
for (q=NULL, p = list.head;p;q=p,p=p->next){
//q 比 p 慢一步
if (p->value[0] == n){
if (q){
//q 是否为空
q->next = p->next;
} else{
list.head = p->next;
}
free(p);
printf("已经删除\n");
print(&list);
break;
}
}
//释放
for (p = list.head;p;p=q){
q = p->next;
free(p);
}
printf("释放完成\n");
return 0;
}
void add(List *pList, int a, int b){
//增加一个节点
Node *p = (Node *)malloc(sizeof(Node));//申请空间
p->value[0] = a; //赋值给 p 节点
p->value[1] = b;
p->next = NULL;
// 查找已有链表的最后那个节点指针
Node *last = pList->head; // 为遍历做准备 last 等于第一个(头节点)
if (last){
//head 不为空
// 遍历
while (last->next){
last = last->next;
}//遍历结束之后,last 就是最后那个
//连接到 p 节点
last->next = p;
}else{
// head 为空, head 指向第一个
pList->head = p;
}
}
void print(List *pList){
Node *p;
for (p = pList->head; p ; p = p->next) {
printf("%d %d\n", p->value[0], p->value[1]);
}
printf("\n");
}
静态链表
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef struct link{
int data; //数据域
int cur; //游标
}component;
void reserveArr(component *array); //创建备用链表
int mallocArr(component *array); //提取备用空间
int initArr(component *array); //初始化静态链表
void show(component *array, int body); //输出链表
int main(){
int body;
component array[11]; //定义一个数组
body = initArr(array);
printf("静态链表、\n");
show(array, body);
return 0;
}
int initArr(component *array){
int body, tempbody, j;
reserveArr(array); // 调用函数创建备用链表
body = mallocArr(array); //调用函数提取备用空间
tempbody = body; //声明一个变量把它当指针使,指向链表的最后一个节点,因为链表为空,所以和头节点重合
for (int i = 0; i < 11; ++i) {
j = mallocArr(array); //从备用链表中拿出空闲的分量
array[tempbody].cur = j; //将申请的空闲分量链接在链表的最后一个节点后面
array[j].data = i; //给新申请的分量数据域初始化
tempbody = j; //将指向链表最后一个节点的指针后移
}
array[tempbody].cur = 0; //新的链表最后一个节点的指针设为0
return body;
}
void reserveArr(component *array){
//创建备用链表
for (int i = 0; i < 11; ++i) {
array[i].cur = i+1; //每个数组分量链接到一起
}
array[10].cur = 0; //链表最后一个节点的游标为0
}
//提取备用空间
//若备用链表为空,则返会分配的节点下标,否则返回0(当分配最后一个节点时,该节点的有标志为0)
int mallocArr(component *array){
int i = array[0].cur;
if (array[0].cur){
//array[0].data = 0;
array[0].cur = array[i].cur;
}
return i; // 返回的是array[0]对应 游标
}
void show(component *array, int body){
int tempbody = body; //tempbody准备遍历使用
while (array[tempbody].cur){
printf("%d--%d\n", array[tempbody].data, array[tempbody].cur);
tempbody = array[tempbody].cur;
}
//输出最后一组
printf("%d---%d\n", array[tempbody].data, array[tempbody].cur);
}
initArr(component *array); //初始化静态链表
void show(component *array, int body); //输出链表
int main(){
int body;
component array[11]; //定义一个数组
body = initArr(array);
printf(“静态链表、\n”);
show(array, body);
return 0;
}
int initArr(component *array){
int body, tempbody, j;
reserveArr(array); // 调用函数创建备用链表
body = mallocArr(array); //调用函数提取备用空间
tempbody = body; //声明一个变量把它当指针使,指向链表的最后一个节点,因为链表为空,所以和头节点重合
for (int i = 0; i < 11; ++i) {
j = mallocArr(array); //从备用链表中拿出空闲的分量
array[tempbody].cur = j; //将申请的空闲分量链接在链表的最后一个节点后面
array[j].data = i; //给新申请的分量数据域初始化
tempbody = j; //将指向链表最后一个节点的指针后移
}
array[tempbody].cur = 0; //新的链表最后一个节点的指针设为0
return body;
}
void reserveArr(component *array){ //创建备用链表
for (int i = 0; i < 11; ++i) {
array[i].cur = i+1; //每个数组分量链接到一起
}
array[10].cur = 0; //链表最后一个节点的游标为0
}
//提取备用空间
//若备用链表为空,则返会分配的节点下标,否则返回0(当分配最后一个节点时,该节点的有标志为0)
int mallocArr(component *array){
int i = array[0].cur;
if (array[0].cur){
//array[0].data = 0;
array[0].cur = array[i].cur;
}
return i; // 返回的是array[0]对应 游标
}
void show(component *array, int body){
int tempbody = body; //tempbody准备遍历使用
while (array[tempbody].cur){
printf(“%d–%d\n”, array[tempbody].data, array[tempbody].cur);
tempbody = array[tempbody].cur;
}
//输出最后一组
printf(“%d—%d\n”, array[tempbody].data, array[tempbody].cur);
}
版权声明
本文为[L-xykeen]所创,转载请带上原文链接,感谢
https://blog.csdn.net/jin_xinyu/article/details/124326638
边栏推荐
- SQL Server database in clause and exists clause conversion
- Using oes texture + glsurfaceview + JNI to realize player picture processing based on OpenGL es
- [play with lighthouse] Tencent cloud lightweight server builds a full platform video analysis video download website
- Openlayers draw rectangle
- Zero cost, zero foundation, build profitable film and television applet
- SSDB Foundation
- 优先使用组合而不使用继承
- 2021-2022-2 ACM集训队每周程序设计竞赛(8)题解
- Go modules daily use
- How to use go code to compile Pb generated by proto file with protoc Compiler Go file
猜你喜欢
ArcMap connecting ArcGIS Server
网络协议之:sctp流控制传输协议
Partage de la conception de l'alimentation électrique de commutation et illustration des compétences en conception de l'alimentation électrique
[record] typeerror: this getOptions is not a function
[report] Microsoft: application of deep learning methods in speech enhancement
The fifth bullet of MySQL learning -- detailed explanation of transaction and its operation characteristics
OpenHarmony开源开发者成长计划,寻找改变世界的开源新生力!
ArcMap连接 arcgis server
Pdf reference learning notes
Use of fluent custom fonts and pictures
随机推荐
[transfer] summary of new features of js-es6 (one picture)
Oracle configuration st_ geometry
机器学习目录
Circuit on-line simulation
How to uninstall easyton
Keysight has chosen what equipment to buy for you
C1000k TCP connection upper limit test
Steps to build a deep learning environment GPU
命令-sudo
MySQL syntax collation (4)
Main differences between go and PHP
The fifth bullet of MySQL learning -- detailed explanation of transaction and its operation characteristics
Client interns of a large factory share their experience face to face
arcgis js api dojoConfig配置
Openlayers draw rectangle
Some speculation about the decline of adults' language learning ability
Wechat applet part of the mobile phone Preview PDF did not respond
Some ideas about time-consuming needs assessment
Is it safe to open an account in Bohai futures.
Executor、ExecutorService、Executors、ThreadPoolExecutor、Future、Runnable、Callable