目录
内存
内存是电脑上特别重要的存储器,计算机中所有程序运行都是在内存中进行的。
所以为了有效的使用内存,就把内存分成一个个小的内存单元,每个内存单元的大小是1个字节。为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
内存的使用跟我们现实生活中的空间的使用有很多相似的地方,我们给国土空间编了很多名字,比如说浙江省杭州市滨江区XX小区X号楼XXXX就可以精准找到一个房间。
1. 内存是怎么编号的?
2. 一个这样的内存单元是多大空间
我们考虑计算机的时候,会说这是32位机器,这是64位机器,32位、64位指的是什么?
32位 —— 有32根地址线 —— 是物理线 —— 可通电 —— 正电是1,负电是0 —— 1/0
32根地址线通上电之后有正负之分,就产生了1/0这样的信号。
电信号转换成数字信息:1和0组成的二进制序列
举例:
总结:int a = 10; //a在内存中要分配空间的
int类型占4个字节,这4个字节都有一个地址,但是&a(取地址a)拿到的是这4个字节的第一个字节的地址,只要拿到连续空间的起始位置的地址,就能找到后面的了。
创建指针变量
#include<stdio.h>
int main(void)
{
int a = 10; //a在内存中要分配空间的 —— 4个字节
//拿到地址以后想把它打印出来怎么办?
printf("%p", &a); //%p 专门用来打印地址
//&a 拿到的是一个地址编号,但是编号也是值,这个值怎么存起来?创建指针变量存起来
int * pa = &a; //pa 是用来存放地址的,在C语言中pa叫指针变量
//* 说明pa 是指针变量
//int 说明执行的对象是int类型
char ch = 'w';
char * pc = &ch; //创建指针变量
//pc指向的类型是char类型
return 0;
}
#include<stdio.h>
int main(void)
{
int a = 10;
//&a 拿到a的地址;
//pa = &a 将地址存到pa里面
//int * pa pa的类型是int
int * pa = &a;
//pa里存的a的地址有什么用?难道仅仅是为了存起来???
//有朝一日,可能会想通过pa存的地址取找a
//怎么找呢?
*pa = 20;
// * 是解引用操作,是单目操作符
// *pa就是通过pa里存的地址,找到a
//此处是找到a之后 把a的值变成 20
printf("%d\n", a); //输出 20
return 0;
}
总结:
指针是用来干什么的?是用来存放地址的
存放谁的地址
指针是有类型的,类型怎么写
指针能用来做什么?
第一是存,第二是以后可通过解引操作符找到所指向的对象,从而操作所指向的对象
pa是指针变量,里面存的就是地址,使用pa就是使用它存的地址,所以指针就是地址
指针变量大小
#include<stdio.h>
int main(void)
{
//32位平台下
printf("%d\n", sizeof(char*)); //输出:4
printf("%d\n", sizeof(short*)); //输出:4
printf("%d\n", sizeof(int*)); //输出:4
printf("%d\n", sizeof(long*)); //输出:4
printf("%d\n", sizeof(long long*)); //输出:4
printf("%d\n", sizeof(float*)); //输出:4
printf("%d\n", sizeof(double*)); //输出:4
return 0;
}
可以看到:
指针的大小是相同的!
为什么?
因为指针是用来存放地址的!
指针需要多大空间,取决于地址的存储需要多大空间!
32位机器上 是由 32bit 组成的二进制序列作为地址 —— 4个字节
64位机器上 是由 64bit 组成的二进制序列作为地址 —— 8个字节
结论:指针大小在32位平台下是4个字节,64位平台是8个字节。
结构体
结构体使得C语言有能力描述复杂对象(复杂类型)
人是复杂对象,不可以用3.1415来描述,人有名字、年龄、姓名、电话、住址等等信息
比如描述学生,学生包含:名字+年龄+性别+学号等信息
比如一本书,包含信息有作者、出版社、定价、分类等信息
C语言怎么描述这些复杂对象?
结构体可以让C语言创建新的类型出来
举例
#include<stdio.h>
//创建一个学生
struct Student
{
char name[40]; //成员变量:名字
int age; //成员变量:年龄
double score; //成员变量:成绩
};
//创建一个书的类型
struct Book
{
char name[50];
float price;
char id[30]; //书号
};
int main(void)
{
//结构体的创建的初始化
struct Student s = { "小明", 17, 78.5 }; //s是结构体变量
struct Book book1 = { "《最后一滴血留给我》", 35, "id:123456789"};
//怎么打印这些信息?
printf("%s %d %.2f\n", s.name, s.age, s.score);
printf("%s %.2f %s\n", book1.name, book1.price, book1.id);
//格式:结构体变量.成员变量
return 0;
}
运行结果:
结构体变量也是变量,下面对s取地址试试:
#include<stdio.h>
//创建一个学生
struct Student
{
char name[40]; //成员变量:名字
int age; //成员变量:年龄
double score; //成员变量:成绩
};
int main(void)
{
//结构体的创建的初始化
struct Student s = { "小明", 17, 78.5 }; //s是结构体变量
//怎么打印这些信息?
printf("1: %s %d %.2lf\n", s.name, s.age, s.score);
//对结构体变量s取地址
struct Student * ps = &s; //struct Student * 为结构体指针类型
printf("2: %s %d %.2lf\n", (*ps).name, (*ps).age, (*ps).score);
//ps是指针,*解引以下变成s
//这种做法比较费劲,下面的方法比较简单
printf("3: %s %d %.2lf\n", ps->name, ps->age, ps->score);
//ps->name 意思是 ps是指针,通过先找到它指向的对象,然后再找到它指向对象的成员name
//格式:结构体指针->成员变量名
return 0;
}
运行结果: