C.8 指针与地址
本文介绍了C语言中内存、指针和数组的基本概念及操作。内存被抽象为字节单元,地址是十六进制编码的字节位置。指针变量存储地址,通过操作符可对地址取值,常用于交换变量值等操作。数组名即首元素地址,指针运算时会自动按数据类型大小调整偏移量。字符串操作中,str表示地址而str表示字符值,二者在指针移动、字符访问时作用不同。文中还演示了字符串拼接、比较等指针应用的代码示例,强调指针操作中地址与值的区别与联系
1.内存
物理意义上的内存:内存条
C语言中的内存是操作系统抽象出来的
计算机最小数据存储单元:字节 1字节==8bit
- 计算机会按照字节对内存进行编码,这个编码就是地址
- 计算机中的地址是一串十六进制数,0x开头
- CPU会根据约束类型对地址取值
特殊地址:(以32位为例)0x00000000(NULL),没有访问权限

2.地址与指针
指针指向的就是地址
2.1 指针变量的定义格式
数据类型 * 变量名称 = 初始化地址
初始化地址一般指向NULL;但不代表就要使用
2.2 相关操作
2.2.1 取地址
用%p控制输出
2.2.2 取值
用*取值
#include <stdio.h>
int main(int argc, const char *argv[])
{
int num =10;
int *p =#
printf("num的地址为%p\n",&num);
printf("p指向的地址为:%p\n",p);
printf("p指向地址的数据为:%d\n",*p);
printf("num对应的数值为:%d\n",*&num);
return 0;
}
习题:
用指针交换两个数的值
#include <stdio.h>
void Swap(int *num1, int *num2);
int main(int argc, const char *argv[])
{
int num1 = 5;
int num2 = 4;
Swap(&num1, &num2);
}
void Swap(int *num1, int *num2)
{
int temp = *num1;
*num1 = *num2;
*num2 = temp;
printf("交换后: num1=%d,num2=%d\n", *num1, *num2);
}
3.数组与指针
3.1数组名
保存的是数组首元素的首地址
#include<stdio.h>
int main(int argc, const char *argv[])
{
int arr[5]={1,2,3,4,5};
printf("arr存储的地址为:%p\n",arr);
printf("arr[0]的首地址为:%p\n",&arr[0]);
printf("arr[1]的地址为:%p\n",&arr[1]);
printf("arr:%d\n",*arr);
}
3.2 数组中地址的加减
3.2.1 加
数组中地址arr+n对应的地址,实际上是arr+n*sizeof(arr[0])
即 地址 加上 对应数据类型所占字节的长度 得到 的地址
int arr[]={1,2,3,4,5,6,7,8,9,0}
arr[5]+3 得到arr[8]的地址
3.2.2 减
arr[5]-arr[3]
结果是 arr[5] 对应元素 的 首地址 与 arr[3] 对应元素 的 首地址 之间相差多少个对应数据类型的长度
int arr[]={1,2,3,4,5,6,7,8,9,0}
arr[5]-arr[3]
=4
3.3数组作为函数参数

3.4 字符串与字符数组
3.4.1 遍历字符串
#include<stdio.h>
int main(int argc, const char *argv[])
{
char ch[]="hello";
char *p =ch;
while (*p !='\0')
{
printf("%c",*p);
p++;
}
printf("\n");
}
3.4.2相关函数
- 拼接
#include<stdio.h>
/**
* 函数功能:实现字符串的拼接,将str2拼接到str1
*
* @param str1 char类型,拼接的目标字符串
* @param str2 char类型,拼接的源字符串
*
* @return 无
*/
void Joint(char *str1,char *str2);
int main(int argc, const char *argv[])
{
char str1[128]="hello";
char str2[]="world";
printf("拼接前的str1为:%s\n", str1);
Joint(str1,str2);
printf("拼接后的str1为:%s\n", str1);
}
void Joint(char *str1,char *str2)
{
while (*str1!='\0')
{
str1++;
}
while (*str2!='\0')
{
*str1=*str2;
str1++;
str2++;
}
*str1 ='\0';
}
- 比较相等
#include <stdio.h>
/**
* 函数功能:比较两个字符串是否相等
*
* @param str1 char类型,比较的第一个字符串
* @param str2 char类型,比较的第二个字符串
*
* @return 无
*/
void Compare(char *str1, char *str2);
int main(int argc, const char *argv[])
{
char str1[128] = "hello";
char str2[] = "worldworld";
Compare(str1, str2);
}
void Compare(char *str1, char *str2)
{
int i = 0;
while (str1[i] != '\0' && str2[i] != '\0')
{
if (str1[i] != str2[i])
{
printf("不相等\n");
}
i++;
}
if (str1[i] == '\0' && str2[i] == '\0')
{
printf("相等\n");
}
else
{
printf("不相等\n");
}
}
4.注意
在实际代码中,str 和 *str 的区别核心在于是否进行解引用操作,具体差异如下:
- 含义不同
str:表示指针变量本身,存储的是内存地址(指向字符串的首地址)。
例如:char *str = "hello"; 中,str 存放的是字符 'h' 的内存地址。*str:表示对指针进行解引用操作,获取的是指针当前指向的具体字符。
例如:上述例子中,*str 等价于字符 'h'(str 指向的第一个字符)。
- 用法场景不同
str 用于操作指针本身
移动指针:str++(让指针指向后一个字符)
比较指针地址:if (str == NULL)(判断指针是否为空)
传递指针:func(str)(将指针作为参数传入函数)
*str 用于操作指针指向的内容
获取字符:char c = *str;(获取当前指向的字符)
修改字符:*str = 'A';(修改当前指向的字符值)
判断字符串结束:while (*str != '\0')(当指向的字符不是结束符时循环)
- 类型不同
str 的类型是指针类型(如 char *)。
*str 的类型是指针指向的数据类型(如 char)。
举例说明
char *str = "hello";
// str 是指针,存储 'h' 的地址
// *str 是 'h',*(str+1) 是 'e',以此类推
printf("指针地址: %p\n", str); // 输出 str 存储的地址(如 0x7f8a1b2c3d4e)
printf("指向的字符: %c\n", *str); // 输出 'h'
总结:
*str在声明时只作为定义一个指针
在使用时,*str 表示取值,str表示地址。
更多推荐


所有评论(0)