C语言指针是C语言中最重要的概念之一。它是一种特殊的变量,它存储了一个内存地址,这个内存地址指向另一个变量的位置。在C语言中,指针是一种非常有用的工具,可以用来处理内存中的数据,使代码更加高效和灵活。本文将从地址、数组、指针的概念解释、指针的命名、指针变量概念解释、
&
符号的作用、*
符号的作用、指针的偏移、指针常量、常量指针的区别等多个方面,来剖析C语言指针的基础知识。
基本概念解释
在开始学习指针之前,我们需要先了解一些相关的概念。
- 地址:是数据在内存中的存储位置编号,是一个常量。
- 数组:是一组相同类型的数据的集合,数组名本身就表示这个数组的首地址。
- 指针:本质上就是地址。
指针的命名和定义
指针的命名遵循类型 *指针变量名
的命名规则,其中*
符号表示这是一个指针变量。例如,int *p
表示定义了一个指向整型数据的指针变量p。
指针变量的使用
指针变量存储的数据是地址,我们可以使用指针变量来访问对应地址的数据。例如,我们可以通过以下代码来获取数组arr的首地址并赋值给指针变量p:
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = arr;
printf("%p\n", p);
return 0;
}
这里的*p
表示访问p所指向的地址上的值,也就是arr[0]
的值。
运行输出
为了顺口,指针变量一般简称为指针。
另外所有类型的指针变量,在64位系统中都占8个字节的内存,在32位系统中都占用4个字节的内存,例如以下代码打印不同类型指针变量的内存占用:
#include <stdio.h>
int main()
{
char *cp = NULL;
int *ip = NULL;
double *dp = NULL;
printf("char p size: %zd\n", sizeof(cp));
printf("int p size: %zd\n", sizeof(ip));
printf("double p size: %zd\n", sizeof(dp));
return 0;
}
运行输出
&
符号的作用
&
符号是取地址符,指针变量取了谁的地址,就指向谁。例如,我们可以通过以下代码来获取变量a的地址并赋值给指针变量p:
#include <stdio.h>
int main()
{
int a = 0;
int *p = &a;
printf("%p\n", p);
return 0;
}
运行输出
*
符号的作用
*
符号有两个作用:一是指针变量的标识,二是解引用,取内容。例如,我们可以通过以下代码来获取指针p所指向的地址上的值:
#include <stdio.h>
int main()
{
int a = 0;
int *p = &a;
printf("%d\n", *p);
return 0;
}
运行输出
指针的偏移
指针的偏移是指指针变量在内存中向前或向后移动一定的偏移量。例如,我们可以通过以下代码来实现指针的偏移:
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = arr;
printf("%d\n", *p);
p+=1;
printf("%d\n", *p);
p+=3;
printf("%d\n", *p);
return 0;
}
指针p += 1,+1代表偏移1次指针对应类型的内存值,运行输出
在char数组中,char指针偏移1个字节相当于指向下一个索引,在int数组中,char指针需要偏移4个字节才能指向下一个索引,以下为演示代码,偏移达到4个字节时,才指向arr[1]
:
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
char *p = (char*)arr;
printf("%d\n", *p);
p+=1;
printf("%d\n", *p);
p+=3;
printf("%d\n", *p);
return 0;
}
运行输出
指针常量和常量指针
指针常量和常量指针是指针的两种特殊类型。
以下是两者的区别:
指针常量:
- 定义时需要初始化
- 定义方式:
*
标识在前,const
常量标识在后,如int * const p
- 不可改变指向,可改变内容
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
// int* const p;
// p = &a; // error: assignment of read-only variable ‘p’
int* const p = &a; // success
printf("%d\n", *p);
// p = &b; // error: assignment of read-only variable ‘p’
*p = 100; // success
printf("%d\n", *p);
printf("%d\n", a);
return 0;
}
运行输出
定义指针常量p时,必须通过一次操作完成初始化,如
int* const p = &a;
,如果分两次操作int* const p;
p = &a;
赋值则会报错,因为指针常量不可改变指向(即地址值)。
定义指针常量后可改变内容,如p原来内容为a的值,等于10,通过操作*p = 100;
变为了100,同时a的值也变为了100;
常量指针:
- 定义时不需要初始化
- 定义方式:
const
常量标识在前,*
标识在后,如const int *p
- 可改变指向,不可改变内容
#include <stdio.h>
const int* p;
int main()
{
int a = 10;
int b = 20;
p = &a;
printf("%d\n", *p);
// *p = 100; // error: assignment of read-only location ‘*p’
p = &b; // success
printf("%d\n", *p);
return 0;
}
运行输出
定义常量指针p时,可通过两步操作完成,
const int* p;
p = &a;
,定义后可改变p的指向,如p原先指向a,打印输出为10,指向b后,打印输出为20。
定义常量指针后不可改变其内容,如通过操作*p = 100;
赋值会报错。
总结
C语言指针是C语言中最重要的概念之一。它是一种特殊的变量,它存储了一个内存地址,这个内存地址指向另一个变量的位置。在C语言中,指针是一种非常有用的工具,可以用来处理内存中的数据,使代码更加高效和灵活。本文从地址、数组、指针的概念解释、指针的命名、指针变量概念解释、&
符号的作用、*
符号的作用、指针的偏移、指针常量、常量指针的区别等多个方面,来剖析C语言指针的基础知识。(Ps:前言偷懒当总结)