目录
指针的定义
指针是能够存放一个地址的一组储存单元(通常是2或4个字节),是用来储存地址的。
p=&c;
将c的地址赋给p,于是p为指向c的指针(当然p要提前声明为指针)
另:char类型占一个字节长度,long类型占连续4个,short占2个。
*符号作用于指针将访问所指向的内容,可理解为解引
指针的声明
char c;
char* p;
p=&c;
其中char* p与char *p写法都能表示正确的指针声明,很多书上和视频教程也表示不一,根据个人习惯理解,但本人还是喜欢靠前更方便,一是按照定义惯例,数据类型都是往变量前面靠,其次之后学习结构体的时候用到typedef函数定义更容易理解,其次很后面那种写法容易犯这种错误
*p=&C
但是char *p,*prt可以一起定义两个指针,但char* p,prt,中prt未定义。 指针的运算
如果理解了指针的用法,指针的运算其实很简单,此处就不加赘述
指针与数组
1.指针与数组的相互转换
由于数组名是数组的首元素的地址,于是
int a[10];
int* pa;
pa=a;
pa指向数组的首元素
若想指向数组第i-1个元素(即a[i])则可以这样pa+i,指针指向首元素后的第i个对象
*(p+i)即表示解引元素的内容
对数组a[i]的引用也可以这样直接表示为*(a+i),事实上a[i],C语言就是先转化为*(a+i),再进行求值所以指针编写的程序比数组执行速度要快
2.指针与数组名的区别
最大的区别就是
指针:变量 pa++,pa=a合法
数组名:常量 a++,a=pa不合法
指针与函数参数
1.传入指针与传入地址的区别
参考其他博主的文章
传递址操作
#include<iostream>
void swap(int& a,int& b) {
int tep = a;
a = b;
b = tep;
}
int main() {
int a = 5;
int b = 4;
std::cout << a << " " << b<<std::endl;
swap(a, b);
std::cout << a << " " << b;
}
这里形参和实参数据类型是相同的,只是在给形参取了地址,传了地址后相当于把这个实参传进来的
传指针操作
#include<iostream>
void swap1(int* a,int* b) {
int *tep = a;
a = b;
b = tep;
}
void swap2(int* a, int* b) {
int tep = *a;
*a = *b;
*b = tep;
}
int main() {
int a = 5;
int b = 4;
int* p = &a;
int* q = &b;
std::cout << a << " " << b<<std::endl;
swap1(p, q);
std::cout << a << " " << b << std::endl;
swap2(p, q);
std::cout << a << " " << b;
}
输出
5 4
5 4
4 5
注意:第一个函数输出值没有改变是因为传入的是指针的副本,实际指针还是这样指向的
第二个直接操作指针对应的数,所以主函数输出会改变
总结:于是我们可以主调函数中传递地址,被调函数传递指针
#include<iostream>
void swap(int* a,int* b) {
int tep = *a;
*a = *b;
*b = tep;
}
int main() {
int a = 5;
int b = 4;
std::cout << a << " " << b<<std::endl;
swap(&a, &b);
std::cout << a << " " << b;
}
输出
5 4
4 5
&a就是一个指向变量a的指针
2.数组做形参
拿strlen函数举例,以前传递数组是这样
int strlen(char s[])
当我们要向函数传递数组时,实际上传递的是该数组的第一个元素的地址,在被调用函数中,该参数是一个局部变量,因此数组名参数必须是一个指针
int strlen(char *s)
在这个函数中
int strlen(char *s)
{
int n;
for(n=0;*s!='\n';s++)
n++;
return n;
}
指针s只是副本,不会影响字符串,且s为指针所以可以自增
3.指针与字符串
只需将字符串当作数组理解即可,详见上一篇字符串笔记
指针的大致需要注意的内容先写到这里,新的知识也会在此记录