C语言核心概念详解:指针的解引用,基本指针运算`*p++` 和 `(*p)++` 的区别

一、字符数组:字符串的存储容器

字符数组是用来存储字符串数据的重要数据结构。

基本定义与初始化

c 复制代码
#include <stdio.h>

int main() {
    // 方式1:逐个字符初始化
    char ch[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
    
    // 方式2:字符串直接初始化
    char str[] = "Hello";
    
    printf("ch: %s\n", ch);
    printf("str: %s\n", str);
    
    return 0;
}

内存布局

| | |
|------|-------|-------|-------|-------|-------|
| 字符数组 | H | e | l | l | o |
| 索引 | [0] | [1] | [2] | [3] | [4] |

自动大小计算

c 复制代码
#include <stdio.h>

int main() {
    char name[] = "张三";  // 编译器自动计算大小(包含\0)
    char city[20] = "北京";
    
    printf("姓名: %s\n", name);
    printf("城市: %s\n", city);
    printf("欢迎%s来到%s!\n", name, city);
    
    // 查看数组大小
    printf("name数组大小: %zu\n", sizeof(name));
    printf("city数组大小: %zu\n", sizeof(city));
    
    return 0;
}

输出结果:

makefile 复制代码
姓名: 张三
城市: 北京
欢迎张三来到北京!
name数组大小: 7
city数组大小: 20

二、字符串的整行输入输出

问题:scanf遇到空格就停止

c 复制代码
#include <stdio.h>

int main() {
    char text[50];
    
    printf("请输入带空格的文本: ");
    scanf("%s", text);  // 遇到空格就停止
    
    printf("输出结果: %s\n", text);  // 只会输出空格前的部分
    
    return 0;//如输入abc  defg只会输出abc要注意
}

解决方案:使用 %[^\n]

c 复制代码
#include <stdio.h>

int main() {
    char sentence[100];
    
    printf("请输入一句话: ");
    scanf("%[^\n]", sentence);  // 读取直到换行符
    
    printf("你输入的是: %s\n", sentence);
    
    return 0;
}

三、指针:直接内存访问的利器

指针的重要性

  • 直接内存访问能力
  • 高效的数据操作
  • 动态内存管理
  • 复杂数据结构的实现
  • 系统级编程支持

指针基础

c 复制代码
#include <stdio.h>

int main() {
    int a = 10;        // 开辟一块内存空间
    int *p = &a;       // 使用&取变量a的地址
    
    printf("变量a的值: %d\n", a);
    printf("变量a的地址: %p\n", &a);
    printf("指针p的值(存储的地址): %p\n", p);
    printf("通过指针p访问的值: %d\n", *p);
    
    return 0;
}

四、指针的解引用

指针的解引用(Dereferencing)是使用指针访问或修改其所指向内存中数据的操作。解引用操作使用 * 运算符。

c 复制代码
#include <stdio.h>

int main() {
    int num = 42;
    int *ptr = &num;  // ptr指向num
    
    // 解引用:通过指针访问指向的值
    printf("num的值: %d\n", num);
    printf("通过指针访问的值: %d\n", *ptr);  // 解引用
    
    // 通过指针修改值
    *ptr = 100;  // 解引用并赋值
    printf("修改后num的值: %d\n", num);
    
    // 验证修改
    printf("再次通过指针访问: %d\n", *ptr);
    
    return 0;
}

五、指针的算术运算

指针的算术运算是C语言中一个强大但需要谨慎使用的特性。与普通算术运算不同,指针运算的结果取决于指针所指向的数据类型。

基本指针运算

c 复制代码
#include <stdio.h>

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    int *ptr = arr;  // 指向数组第一个元素
    
    printf("初始位置:\n");
    printf("ptr = %p, *ptr = %d\n", ptr, *ptr);
    
    // 指针加法
    ptr = ptr + 1;  // 移动到下一个int元素
    printf("ptr + 1:\n");
    printf("ptr = %p, *ptr = %d\n", ptr, *ptr);
    
    ptr = ptr + 2;  // 再向后移动两个int元素
    printf("ptr + 2:\n");
    printf("ptr = %p, *ptr = %d\n", ptr, *ptr);
    
    // 指针减法
    ptr = ptr - 1;  // 向前移动一个int元素
    printf("ptr - 1:\n");
    printf("ptr = %p, *ptr = %d\n", ptr, *ptr);
    
    return 0;
}

六、*p++(*p)++ 的区别

*p++ - 指针移动

  • 先计算 *p(获取当前指针指向的值)
  • 然后执行 p++(指针向后移动一个元素位置)
  • 返回之前获取的值
c 复制代码
#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40};
    int *p = arr;
    
    printf("*p++ = %d\n", *p++);   // 输出:10
    printf("当前 *p = %d\n", *p);   // 输出:20(指针已移动)
    printf("arr[0] = %d\n", arr[0]); // 输出:10(原值未变)
    
    return 0;
}

(*p)++ - 值修改

  • 先计算 *p(获取指针指向的值)
  • 然后对该值执行 ++(将指针指向的内存位置的值加1)
  • 返回之前获取的值
  • 指针位置不变
c 复制代码
#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40};
    int *p = arr;
    
    printf("(*p)++ = %d\n", (*p)++); // 输出:10
    printf("当前 *p = %d\n", *p);       // 输出:11(值已改变)
    printf("arr[0] = %d\n", arr[0]);   // 输出:11(原数组被修改)
    
    return 0;
}

使用场景:

  • *p++ - 关注指针移动(常用于遍历数组)
  • (*p)++ - 关注值的修改(修改指针指向的内容)
相关推荐
申阳2 小时前
Day 9:07. 基于Nuxt开发博客项目-工具箱整理
前端·后端·程序员
jtymyxmz2 小时前
1.1.4 Spring的下载及目录结构
java·后端·spring
robch2 小时前
Spring 的 DelegatingFilterProxy 用法
java·后端·spring
CodeSheep3 小时前
稚晖君公司的最新工资和招人标准
前端·后端·程序员
ashane13143 小时前
Springboot 启动过程及源码分析
java·spring boot·后端
不会kao代码的小王3 小时前
零基础也能搭博客?
linux·windows·后端
程序员爱钓鱼3 小时前
Python编程实战 - Python实用工具与库 - 爬虫防封与代理机制
后端·python·ipython
程序员爱钓鱼3 小时前
Python编程实战 - Python实用工具与库 - 操作Excel:openpyxl / pandas
后端·python·面试
后端小张3 小时前
【JAVA进阶】SpringBoot启动流程深度解析:从main方法到应用就绪的完整旅程
java·spring boot·后端·spring·spring cloud·java-ee·流程分析