初始指针和结构体

指针

指针,算是C语言的一大难点内容了,要将指针,首先来认识一下内存

内存

我们计算机的内存区域被分成了这样一个个小的内存单元

每个小格子被称作内存单元,,这些数字称作内存单元的编号

也称作地址

一个内存单元的大小为一个字节

在32位机器上,拥有着32跟地址线地址线通电后,电信号转换为数字信号就是1/0(低电平为0,高电平为1)

通电后产生的所有可能性为:

共有2的32次方种可能

每一个二进制序列都会作为内存单元的编号

共有2的32次方个地址,一个地址占一个字节的空间,所以共能管理2的32次方个字节的空间

2的32次方字节 = 4294967296字节/1024/1024/1024 = 4GB空间

每个内存单元的编号就称作地址,C语言中把地址称作指针

编号 == 地址 == 指针

a要向内存申请4个字节的空间

&

取地址符号

%p

打印地址 ,显示的是16进制的数值

打印出来一个地址

我们调试并打开内存窗口

a所占的空间就是这4个字节

我们打开内存窗口,将每一列设置为1行,就会发现这些小格子就是一个内存单元

关于我们的10为什么会写成

0a 00 00 00

我们10的二进制序列是

00000000 00000000 00000000 00001010

为了方便,我们可以将而进制转换为16进制,四个2进制可以转换为16进制

依次转换为00 00 00 0a (2进制的1010是10,16进制的10~15就用a~f来表示)

这个数据在内存中是倒着放的

取地址然后把地址存起来,这里的pa就叫指针变量,因为a的类型是int,所以pa的类型就是*pa

* 说明pa就是指针变量

int 说明pa指向的对象就是int类型的

举一反三:

指针,本质是地址

口头语中,说的指针是指:指针变量

这里的*是解引用操作符,意思是通过pa里面存放的地址,找到它所指向的对象

*pa 就是a

而这里的*pa = 20;的意思是给 a 赋值20

在64位的环境下打印出来的结果全是8,跟类型毫无关系

我们有时候并不能得到a 只能得到a的地址,所以才会用*

好了,初识就先到这,后面再细讲

现在再认识一下另一个以后会常见的知识点——结构体

结构体

人: 名字+年龄+性别+电话+住址

书:书名+作者+出版社+定价+书号

对于复杂对象的描述,C语言提供了结构体

结构体应用

结构体变量.结构体成员

我们也可以使用指针,打印

还可以这样表示

还可以自己输入然后打印

因为age是变量名,所以需要取地址

<think>我们正在讨论C语言指针结构体的语法。首先,我会从基础概念开始,然后逐步深入,结合代码示例进行说明。最后,我会生成一些相关问题。 ### 1. 指针基础 指针是存储变量内存地址的变量。语法如下: ```c int *ptr; // 声明一个整型指针 int num = 10; ptr = &num; // ptr指向num的地址 ``` 访问指针指向的值(解引用): ```c int value = *ptr; // value = 10 ``` ### 2. 结构体基础 结构体用于将多个不同类型的变量组合成一个单一类型。 ```c struct Point { int x; int y; }; ``` 声明结构体变量: ```c struct Point p1; // 声明一个Point类型的变量 p1.x = 3; // 访问成员 p1.y = 4; ``` ### 3. 指针结构体结合 #### 3.1 指向结构体指针 ```c struct Point *ptr = &p1; // 指向结构体指针 ``` 通过指针访问结构体成员有两种方式: - 使用`->`运算符 - 使用`(*ptr).`(注意括号,因为`.`的优先级高于`*`) ```c int x_coord = ptr->x; // 推荐方式 int y_coord = (*ptr).y; // 等效方式 ``` #### 3.2 动态分配结构体 使用`malloc`动态分配结构体内存: ```c #include <stdlib.h> struct Point *dynamic_point = (struct Point*)malloc(sizeof(struct Point)); if (dynamic_point != NULL) { dynamic_point->x = 5; dynamic_point->y = 10; // 使用完后释放内存 free(dynamic_point); } ``` ### 4. 结构体包含指针成员 当结构体中包含指针成员时,需要注意内存管理: ```c struct Person { char *name; // 指向字符串的指针 int age; }; struct Person p2; p2.name = (char*)malloc(50 * sizeof(char)); // 分配内存 if (p2.name != NULL) { strcpy(p2.name, "Alice"); p2.age = 30; // 使用后释放 free(p2.name); } ``` ### 5. 结构体嵌套 结构体可以嵌套其他结构体: ```c struct Rectangle { struct Point top_left; struct Point bottom_right; }; struct Rectangle rect; rect.top_left.x = 0; rect.top_left.y = 10; rect.bottom_right.x = 20; rect.bottom_right.y = 0; ``` ### 6. 代码示例:结构体指针的综合应用 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> struct Student { char *name; int age; float gpa; }; int main() { // 静态分配 struct Student s1; s1.name = "John"; // 指向字符串常量,不需要释放 s1.age = 20; s1.gpa = 3.5; // 动态分配 struct Student *s2 = (struct Student*)malloc(sizeof(struct Student)); if (s2 == NULL) { printf("Memory allocation failed.\n"); return 1; } s2->name = (char*)malloc(50 * sizeof(char)); if (s2->name == NULL) { free(s2); printf("Memory allocation failed.\n"); return 1; } strcpy(s2->name, "Jane"); s2->age = 22; s2->gpa = 3.8; printf("Student 1: %s, %d, %.2f\n", s1.name, s1.age, s1.gpa); printf("Student 2: %s, %d, %.2f\n", s2->name, s2->age, s2->gpa); // 释放动态分配的内存 free(s2->name); free(s2); return 0; } ``` ### 7. 关键注意事项 1. **指针初始化**:声明指针后,应初始化为`NULL`,并在使用前检查。 2. **内存管理**:动态分配的内存必须手动释放,避免内存泄漏。 3. **结构体复制**:直接复制结构体会进行浅拷贝。若结构体包含指针,复制后两个结构体指针成员将指向同一块内存,修改一个会影响另一个。深拷贝需要手动复制指针指向的内容。 4. **结构体大小**:结构体的大小可能因内存对齐而大于成员大小之。使用`sizeof`获取实际大小。 ### 8. 相关问题 §§相关问题§§ 1. C语言中如何实现结构体的深拷贝? 2. 结构体内存对齐的规则是什么?如何控制对齐方式? 3. 函数指针作为结构体成员有什么作用?请举例说明。</think>### C语言指针结构体语法详解 #### 一、指针基础语法 指针是存储内存地址的变量,语法核心是`*``&`运算符: ```c int num = 10; // 普通变量 int *ptr = &num; // 指针变量(存储num的地址) printf("值: %d\n", *ptr); // 输出10(解引用) printf("地址: %p\n", ptr); // 输出内存地址 ``` **关键概念**: 1. 声明:`数据类型 *指针名;` ```c float *f_ptr; // 浮点指针 char *c_ptr; // 字符指针 ``` 2. 指针运算: ```c int arr[3] = {1,2,3}; int *p = arr; p++; // 移动sizeof(int)字节,指向arr[1] ``` #### 二、结构体基础语法 结构体是自定义复合数据类型: ```c // 定义结构体类型 struct Student { char name[50]; int id; float gpa; }; // 声明结构体变量 struct Student s1; s1.id = 101; // 成员访问 strcpy(s1.name, "Alice"); ``` #### 三、指针结构体结合 ##### 1. 结构体指针 ```c struct Student *s_ptr = &s1; printf("ID: %d\n", s_ptr->id); // 用->访问成员 printf("Name: %s\n", (*s_ptr).name); // 等效写法 ``` ##### 2. 动态内存分配 ```c // 动态创建结构体 struct Student *s2 = (struct Student*)malloc(sizeof(struct Student)); s2->id = 102; // 使用后释放 free(s2); ``` ##### 3. 结构体包含指针 ```c struct Profile { char *name; // 指针成员 int age; }; struct Profile p1; p1.name = (char*)malloc(50 * sizeof(char)); // 分配内存 strcpy(p1.name, "Bob"); free(p1.name); // 必须手动释放 ``` #### 四、高级应用示例 **链表实现**: ```c struct Node { int data; struct Node *next; // 自引用指针 }; // 创建链表 struct Node *head = NULL; head = (struct Node*)malloc(sizeof(struct Node)); head->data = 10; head->next = (struct Node*)malloc(sizeof(struct Node)); head->next->data = 20; head->next->next = NULL; ``` #### 五、核心注意事项 1. **指针初始化**: ```c int *ptr = NULL; // 避免野指针 ``` 2. **内存管理**: - `malloc/calloc`分配堆内存 - `free`释放内存(避免泄漏) 3. **结构体传参**: ```c // 传指针效率更高(避免拷贝整个结构体) void printStudent(const struct Student *s) { printf("ID: %d\n", s->id); } ``` #### 六、综合示例 ```c #include <stdio.h> #include <stdlib.h> typedef struct { // 使用typedef简化 int x; int y; } Point; int main() { // 动态创建结构体数组 Point *points = (Point*)malloc(3 * sizeof(Point)); // 初始化数据 for(int i=0; i<3; i++) { points[i].x = i*10; points[i].y = i*20; } // 通过指针访问 Point *ptr = points; printf("Point 1: (%d, %d)\n", ptr->x, (ptr+1)->y); free(points); // 释放内存 return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值