自学内容网 自学内容网

C语言指针基础笔记

C语言指针基础笔记

1. 地址和指针的概念

指针是用来存储内存地址的变量。每个内存单元都有唯一的地址。内存地址是一个无符号整数,表示数据在内存中的位置。

示例代码

#include <stdio.h>

int main() {
    int a = 10;
    printf("变量a的值: %d\n", a);
    printf("变量a的地址: %p\n", &a);
    return 0;
}

2. 直接访问和间接访问

直接访问是通过变量名直接获取其值。间接访问是通过变量的地址获取其值。

示例代码

#include <stdio.h>

int main() {
    int a = 10;
    int *p;         // 定义一个指针变量
    p = &a;         // 将变量a的地址赋值给指针p
    printf("直接访问a的值: %d\n", a);
    printf("间接访问a的值: %d\n", *p);  // 使用指针p访问a的值
    return 0;
}

3. 指针变量与指针运算符

指针的定义

int *ptr;   // ptr是一个指向int类型的指针
  • * 是解引用运算符,用于访问指针所指向的值。
  • & 是取地址运算符,用于获取变量的地址。

示例代码

#include <stdio.h>

int main() {
    int a = 20;
    int *p = &a;
    printf("a的值: %d\n", a);
    printf("a的地址: %p\n", &a);
    printf("p存储的地址: %p\n", p);
    printf("p指向的值: %d\n", *p);
    return 0;
}

从功能上来说,int* pint *p 完全没有区别,它们都是在声明一个整型指针变量。区别仅在于编码风格:

int* p 风格

int* p;    // 强调 int* 是一个类型整体

这种写法的支持者认为这样更直观地表达"p是一个int型指针"的概念,因为把int*当作一个整体类型来看。

int *p 风格

int *p;    // 强调 * 是与变量名结合

这种写法的支持者(包括C语言创始人 Dennis Ritchie)认为这样更准确地反映了C语言的声明语法,特别是在同时声明多个变量时更不容易出错。最关键的区别在于多变量声明时的表现:

int* p1, p2;    // p1是指针,但p2是普通int变量!
int *p1, *p2;   // p1和p2都是指针

因为*是绑定到变量名而不是类型的,所以第一种写法可能会造成误解,认为p1和p2都是指针。这也是为什么很多C语言程序员推荐使用int *p的写法,或者干脆一行只声明一个指针变量:

int *p1;    // 更清晰的写法
int *p2;

4. 指针的基本操作

4.1 给指针赋值

int a = 10;
int *p = &a;

4.2 通过指针修改变量的值

*p = 20;  // 修改a的值为20

4.3 使用NULL指针

int *p = NULL;  // 空指针,防止指针悬挂

示例代码

#include <stdio.h>

int main() {
    int a = 10;
    int *p = &a;
    *p = 20; // 通过指针修改a的值
    printf("a的值: %d\n", a);
    return 0;
}

5. 指针与数组

数组名本质上是一个常量指针,指向数组的第一个元素地址。指针可以通过ptr + i的形式访问数组元素。

示例代码

#include <stdio.h>

int main() {
    int array[5] = {1, 2, 3, 4, 5};
    int *p = array;  // 数组名是常量指针,指向第一个元素

    for(int i = 0; i < 5; i++) {
        printf("array[%d]的地址: %p\n", i, p + i);
        printf("array[%d]的值: %d\n", i, *(p + i));
    }
    return 0;
}

6. 指针与字符串

6.1 字符数组与字符指针的区别

  • 字符数组:包含的是具体的字符内容
  • 字符指针:指向一个字符串常量的首地址

示例代码

#include <stdio.h>

int main() {
    char str1[] = "Hello";          // 字符数组
    char *str2 = "World";           // 字符指针
    printf("str1: %s\n", str1);
    printf("str2: %s\n", str2);
    return 0;
}

7. 指针作为函数参数

通过指针交换两个变量的值

#include <stdio.h>

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 5, y = 10;
    printf("交换前: x=%d, y=%d\n", x, y);
    swap(&x, &y);
    printf("交换后: x=%d, y=%d\n", x, y);
    return 0;
}

8. 指针的常见错误

  • 未初始化的指针
int *p;
*p = 10; // 错误:p未初始化,指向未知地址
  • 指针越界
int arr[5];
int *p = arr;
p[10] = 100; // 错误:越界访问
  • 释放了非法内存
int *p;
free(p); // 错误:p未分配内存

原文地址:https://blog.csdn.net/qq_59611876/article/details/145168096

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!