大家好,这里是永恒,怎么可能。本文主要是对还未整理的c语言一些知识的汇总,后面会写一些使用办法及有趣的小测试,敬请期待哈哈哈,容易拖更。
一、#define定义常量与宏
1、#define定义标识符常量
#define num 20
#include<stdio.h>
int main()
{
int arr[10] = { 0 };
int brr[num] = { 0 };
return 0;
}
我们运行代码的时候,程序是没有警告信息的,那么就说明我们定义的num是有效的。
此时的num就是一个常量,值为10.num=10,10=num。
标识符是常量的符号,也就是说num是10的符号,10是num的值。
1、#define定义宏
#define ADD(x,y)((x)+(y))
#include<stdio.h>
int main()
{
int sum = 0;
sum = ADD(1, 2);
printf("%d\n", sum);
return 0;
}
这里的宏跟函数很像,但宏不是函数,更像一种替换。比如这里的1,2就是去替换了x,y。使得1+2=3,那么这时候我们打印sum其实就是打印1+2的结果。
宏在平时使用的时候要注意多加括号,不然容易报错。
宏不是函数,是一种替换。计算机是严格的机器,我们不要主观的去添加一些思维,使用的时候多加括号,避免报错。
二、关于指针的基础知识
概念
为了访问内存中的内容,给每个内存单元一个编号,我们称这个编号为地址,也就是指针。
编号=地址=指针。
指针是一种数据类型, 所以指针也有自己的内存 ,用来存储地址(编号)
指针的重点
指针本身的类型 除去指针名,剩下的就是指针本身的类型
int *p,去掉p -> int *
指针指向的类型 除去指针名和一个*,剩下的就是指针指向的类型
int *p,类型是int。
所有的指针,无论类型,在内存中都占四个字节的内存
(包括double类型)
指针指向的内存 可以是各种类型
int* p;//类型int
//变量名*p
int* p;//本身类型int*
//指针名p
int* p;//指针指向类型int
//指针名p
int main()
{
char* p;
short* q;
int* w;
float* e;
double* r;
printf("%d\n", sizeof(p)); // 8
printf("%d\n", sizeof(q)); // 8
printf("%d\n", sizeof(w)); // 8
printf("%d\n", sizeof(e)); // 8
printf("%d\n", sizeof(r)); // 8
//指针存储地址的内存都是八个字节
//64位机器为8,32位机器为4,更早时候的16位机器为2
return 0;
}
‘*’定义的时候表示定义指针,其他时候为解引用操作符
&为取地址操作符
int main()
{
int a = 10;
int* p = &a;//取地址
printf("%d\n", *p);//10
return 0;
}
置空指针 (null)
有时候,指针定义好了,但是暂时没有指向
或者是,指针用完了,没有指向了
指针不知道指向哪里,就会在程序里面乱跑,可能会指向一些重要内容。
此时的指针,也就是常说的野指针,就很危险了。
所以 这些情况下的指针
统一指向一个地址 指向0地址(null)
int* p = NULL;
int* p = (int*)0x0;
三、结构体的简单应用
在c语言中,我们知道有很多的数据类型,比如short,long,int,char。还知道可以用数组来存放多个数据类型。
数组能存放的数据类型很多,可是单个数组只能存放一种数据类型。如果我们要建立学生信息这样的数据时,学生的信息,包含学生名称、学号、性别、年龄等信息,不同的类型要怎么存放呢?
这个时候就要用到结构体了,结构体能够使多个不同类型的数据存放到一起,而且结构体中还能存放结构体。
我们先来写一个简单的日期表示一下结构体常用的两种办法
自己画的图,见谅哈哈哈
struct day
{
unsigned short year;
unsigned char mon;//unsigned是无符号整形的意思,前面的文章有讲到
unsigned char day;
};
int main()
{
struct day today;
today.year = 2022;
today.mon = 7;
today.day = 23;
printf("%d-%d-%d\t", today.year,today.mon,today.day);
return 0 ;
}
typedef struct
{
short year;
char mon;
char day;
}day;
int main()
{
day today;
today.year = 2022;
today.mon = 7;
today.day = 23;
printf("%d-%d-%d\t", today.year, today.mon, today.day);
return 0;
}
typedef之前有讲过是类型重定义的意思
这两种方法是最常用的,至于用哪种取决于个人喜好
那么肯定有人说,结构体怎么存放结构体呢,我们往下看
struct day
{
unsigned short year;
unsigned char mon;
unsigned char day;
};
struct student
{
char name[20];
short number;
char sex;
struct day ;
};
int main()
{
struct day today ;
today.year = 2000;
today.mon = 7;
today.day = 23;
struct student boy = { "goudan",11,'m',{2000 - 7 - 23} };
printf("%s,%d,%c,%d-%d-%d\t",boy.name,boy.number,boy.sex, today.year, today.mon, today.day);
return 0;
}
我们把这位同学的出生日期放到个人信息里面,代码运行起来就显示出了我们想要的信息。
那我们有没有想过,用结构体输出数组呢
struct day
{
unsigned short year;
unsigned char mon;
unsigned char day;
};
int main()
{
char i;
struct day today[5] = { {2022,7,23 }, {2021, 7, 23}, {2020, 7, 23}, {2019, 7, 23}, {2018, 7, 23} };
for (i = 0; i < 5; i++)
{
printf("%d-%d-%d\t", today[i].year, today[i].mon, today[i].day);
}
return 0 ;
}
指针下标是从0开始的,所以i从0开始循环。
使用结构体输出数组的时候要注意加括号和循环的使用。
既然数组都学到了,要不我们再看看结构体指针如何指向类型吧~
typedef struct
{
unsigned short year;
unsigned char mon;
unsigned char day;
} day;
int main()
{
day today = { 2022,7,23 };
day *pddtoday;
pddtoday = &today;
printf("%d-%d-%d\n", (*pddtoday).year, (*pddtoday).mon, (*pddtoday).day);
printf("%d-%d-%d\t", pddtoday->year, pddtoday->mon, pddtoday->day);
return 0;
}
取地址和解引用操作符上面讲指针的时候有提到过。
我们一开始的时候定义了结构体变量today,现在又定义了结构体指针变量pddtoday。
pddtoday可以指向today,我们可以用*pddtoday输出,也可以用pddtoday指向today输出。
如果逻辑表达上有什么问题欢迎评论指出,有不懂的地方也欢迎留言~
it不易,我们一起加油吧!