补充:一维数组的数组名也是数组的首地址,是地址常量,不能为左值(=左边),不能被重新赋值。
指针运算
指针运算有算术运算、关系运算
算术运算:
nt a[5]={2,13,4,5,6};
// char a[]="hello";
int *p=a;
printf("%p\n",p);
printf("%d\n",*p);
p++;//p=p+1 //指针向高地址方向移动一个数据单位(int 4字节;char 1字节),指针的指向发生改变
printf("%p\n",p);
printf("%d\n",*p);
int a[5]={2,13,4,5,6};
// char a[]="hello";
int *p=a;
printf("%p\n",p);
printf("%p\n",p+2); //指针访问高地址方向第n个元素,指针的指向不发生改变
printf("%p\n",p);
p++ //指针向高地址方向移动一个数据单位(int 4字节;char 1字节),指针的指向发生改变。p+2 //指针访问高地址方向第n个元素,指针的指向不发生改变。
p++里面含有等号,相当于重新赋值。p+2中无等号,所以只是临时访问。
同一个数组,两个地址之间的差值=相差元素个数。
关系运算
< > ==
同一个数组下比较,才有意义,且高地址>低地址。
*p++是先算++,出特殊情况外,都是从右往左。
指针的大小
int a=3;
int *p1=&a;
printf("%d\n",sizeof(p1));
char b='q';
char *p2=&b;
printf("%d\n",sizeof(p2));
getconf LONG_BIT 查看操作系统位数
32位操作系统 ,指针大小为4字节 ,1字节==8位
8位16进制 4*8=32位二进制 =4字节。
64位操作系统 ,指针大小为8字节。
练习:字符数字char a[]=“1234”; —》num=1234;
#include<stdio.h>
int main(int argc, char const *argv[])
{
int num=0;
char a[]="1234";
char *p=a;
while(*p!='\0')
{
num=10*num+(*p-'0');
p++;
}
printf("%d\n",num);
return 0;
}
练习:编写一个程序实现功能:将字符串“Computer Science”赋值给一个字符数组,然后从第一个字母开始间隔的输出该字符串,用指针完成。结果:Cmue cec
段错误
Segmentation fault (core dumped)
详细介绍点击链接
指针虽然灵活好用但是用不好会出现段错误。出现的原因有:访问不存在的内存地址、访问系统保护的内存地址 、访问只读的内存地址、空指针废弃 (eg:malloc与free释放后,继续使用) 、堆栈溢出、内存越界 (数组越界)、访问不存在的内存地址。
练习:字符串倒序
#include<stdio.h>
#include<string.h>
int main(int argc, char const *argv[])
{
char a[]="hello",n;
char *p=a;
char *q=p+strlen(a)-1;
while(p<q)
{
n=*p;
*p=*q;
*q=n;
p++;
q--;
}
puts(a);
return 0;
}
循环输入一个五位数,判断是否是回文数,当输入0时结束。
#include<stdio.h>
#include<string.h>
int main()
{
char *p=a;
char *q=p+strlen(a)-1;
int test=1;
while(p<q)
{
if(*p!=*q)
test=0;
p++;
q--;
}
if(test==1)
printf("yes\n");
else
printf("no");
}
指针修饰
const void
const常量化 read-only
修饰普通变量,不能直接通过变量名进行修改,应通过指针修改。
修饰指针,指针指向的内容不能修改,但是指针的指向可以修改。
修饰p, 指针的指向不能改,指针指向的内容可以改。