【C语言基础】Chap. 4. 初识指针和结构体

1. 指针

了解指针前,首先要明确内存的定义:内存是电脑上重要的存储器,计算机中所有程序的运行都是在内存中进行的。

所以为了有效地使用内存,大多数现代计算机都把内存分割成一个个小的内存单元

而为了能够有效地访问到内存的每个单元,计算机又给内存单元进行了编号,以与其他内存单元进行区分,这些编号就被称为该内存单元的地址(address)。

此时就引出两个问题:

  1. 内存是怎么编号的?

 答:计算机的32位和64位实际上指的是该计算机地址线的根数,它们的通电与否分别代表1和0,这就是把电信号转换成数字信息——二进制序列。以32位为例,其能够产生的如总共有2的32次方个的序列,就可以作为内存单元的编号(地址)。如下:

 
00000000000000000000000000000000
...
00000000000000001111111111111111
...
11111111111111111111111111111111
2.一个内存单元是多大空间?

 答:每个内存单元的大小是1个字节,即8个比特。

在C语言中添加数据(如变量)时,会给对象分配空间(内存单元),而想要访问这个对象的地址,就需要利用取地址运算符&获取其地址——第一个字节的地址。示例:

 

int a = 10; //a在内存中要分配空间,int类型为4个字节
printf("%p\n", &a); //%p 是专门用来打印地址的
int* pa = &a; 

这段代码中的变量pa是用来存放地址的,在C语言中被称为指针变量(pointer variable),也可以叫指针(pointer)。

(但指针实际上是一个抽象概念,大部分情况下既可以指指针变量,也可以指地址,如果一时无法理解,最好在使用中逐渐领会,而不要强行下定义。)

对于这个指针变量,我们会说:pa“指向”a

声明它时int后的*说明其是指针变量,而int说明pa指向的对象是int类型的。

指针变量的声明可以和其他变量一起进行:

int a, b, arr[5], * p;

并且,指针是可以传递的,将上面的pa的值赋给另一个指针变量,它们将同时指向a

int* pb;
pb = pa;

获取地址后就能够通过解引用操作符*,来访问地址,对该对象进行操作:

int a = 10;
int* pa = &a;
*pa = 20; //*pa就是通过存储在pa里面的地址找到a
printf("%d\n", a); //20

因为pa指向a,所以也可以说*paa别名

*pa不仅值与a相同,实际上本质也相同。对*pa的改变也会产生对a的改变。

其实倒不如说,改变*pa就是改变a,这一点要千万注意。

而指针变量本身的大小是多少呢?

printf("%d\n", sizeof(char*)); //4 或 8
printf("%d\n", sizeof(short*)); //4 或 8
printf("%d\n", sizeof(int*)); //4 或 8
printf("%d\n", sizeof(long*)); //4 或 8
printf("%d\n", sizeof(long long*)); //4 或 8
printf("%d\n", sizeof(float*)); //4 或 8
printf("%d\n", sizeof(double*)); //4 或 8

 

实际上,指针的大小是相同的,因为指针是用来存放地址的,指针需要多大空间,取决于地址的存储需要多大空间——即4或8取决于是32位平台还是64位平台。

2. 结构体

结构体(Struct)也叫结构,是C语言的重要知识点,它使得C语言有能力描述复杂类型

如果有学过JavaScript或其他某些语言,会发现结构体与对象、记录等的概念十分相似,它是可能具有不同类型的值的集合,这些值被称为结构体的成员

当我们需要存储一组相关数据项,而且这些数据的类型不完全相同时,结构体是理想的选择。

简单示例:

//模拟一个学生的简单结构体,Stu是student的缩写
struct Stu
{
    //成员变量
    char name[20];
    int age;
    double score;
};

int main()
{
    struct Stu s = { "张三", 20, 85.5 }; //结构体的创建和初始化
    
    //读取方式1:结构体变量.成员变量
    printf("1:%s %d %lf\n", s.name, s.age, s.score);
    
    struct Stu* ps = &s; //结构体类型的指针
    
    //读取方式2:结构体指针解引用.成员变量名
    printf("2:%s %d %lf\n", (*ps).name, (*ps).age, (*ps).score);
    
    //读取方式3:结构体指针->成员变量名
    printf("3:%s %d %lf\n", ps->name, ps->age, ps->score);
    
    //以上三种读取方式的结果都是 张三 20 85.500000
    
    return 0;
}

:每个结构体代表一个新的作用域,因此在这个作用域里声明的名字都不会和程序中的其他名字冲突。C语言表述为:每个结构体都为它的成员设置了独立的命名空间(name space)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值