字节:是内存中最小的储存单位,不同的数据类型在内存中占的大小也不一样
内存地址:为了正确的访问内存单元上的数据,我们人为的给每个内存起上编号,这个编号就是内存的地址
访问数据的方式:
直接访问方式—>通过变量名
间接访问方式—>通过地址访问
指针是一个地址
int a=3;
定义一个整型变量,值为 3
开辟了一块 4 个字节的内存空间,空间名为 a,a 空间存放的数据是 3
printf("a=%d\n",a);
通过变量名直接获取该内存空间上的数据
1、* 在定义指针的时候,是指针的标识符
2、指针的赋值一定要是地址
3、指针前面的数据类型不是修饰指针的,而是修饰指针指向的内存空间上面的数据类型
4、指针在内存中占 4 个字节 (在 64 位编译器里占 8 个字节)
5、* 在使用的时候,表示取内容符号,意思是把指针对应的内存空间上的数据读取出来
*:取内容
&:取地址
*和&是相反的操作
int a=3;
int *p=&a;
printf("a=%d\n",*p);
printf("指针在内存中占的字节数为%d\n",sizeof(p));
运行结果
int a=3;
int *p=&a;
char c='c';
char*p1=&c;
printf("a=%d\n",*p);
printf("a在内存中的地址为%p\n",&a);
printf("p1在内存中占的字节数为%d\n",sizeof(p1));
运行结果
指针换指向
1、当我们在定义一个指针的时候需要加 *
2、当我们需要使用指针指向的内存空间上的数据的时候需要加 *
3、当我们只需要使用内存地址的时候,不需要加 *
#include "stdafx.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
int x=3;
int z=4;
int *p2=&x;
printf("x=%d\n",*p2);
p2=&z;
printf("p2上的内容为%d\n",*p2);
//直接使用变量
printf("通过变量名直接操作变量,z=%d\n",z);
//得到z的内存地址
printf("z的内存地址为%p\n",&z);
//使用指针间接访问数据
printf("通过指针p2操作z空间上的数据为%d\n",*p2);
//指针p2的含义
printf("p2上的内容为%p\n",p2);
//打印指针自己的内存地址
printf("p2自己在内存中的地址是%p\n",&p2);
return 0;
}
运行结果
内存分析图
指针和数组
int array[]={1,3,5,7,9};
1、数组在内存中是一块连续的内存空间
2、假设 a[0] 在第 2000 块内存上,那么 a[2] 在 2008
3、数组名代表首元素的地址
int *p3=array;
1、指针 p3 指向了数组 array 的首元素地址
2、数组指针:指向数组的指针
3、指针数组:实质上是数组,只不过是数组里面存放的是指针而已
#include "stdafx.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
int array[]={1,3,5,7,9};
int *p3=array;
//数组名的含义
printf("array数组名的含义是%p\n",array);
//首元素地址
printf("array首元素的地址为%p\n",&array[0]);
//方式1:使用数组获取第二个元素的值
printf("array第二个元素的值为%d\n",array[1]);
printf("通过指针间接操作%d\n",*p3);
//方式2:通过指针偏移获取下一块内存(数组第二个元素的值)
printf("通过指针偏移得到数组中的第二个元素的值为%d\n",*(p3+1));
//先获取p3上的数据,然后再把这个数据+1
printf("%d\n",*p3+1);
//方式3:只要是地址,都可以通过加减偏移的
printf("%d\n",*(array+1));
//方式4
printf("%d\n",p3[1]);
return 0;
}
运行结果
指针和字符串
1、在 C 语言中,我们使用字符数组表示字符串
2、字符指针:一个指针指向字符数组的首元素地址
#include "stdafx.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
char str[10]="iPhone";
printf("str的长度为%d\n",sizeof(str));
char *p=str;
//打印iPhone
printf("str=%s\n",str);
printf("str=%s\n",p);
//打印iPhone中的P字母
printf("打印iPhone中的%c\n",str[1]);
printf("用指针的形式打印%c\n",*(p+1));
//利用指针计算字符串的长度
char s[]="hbsaldf";
char *p1=s;
int length=0;
while(*(p1+length)!='\0')
{
length++;
}
printf("这个字符串的长度为:%d\n",length);
return 0;
}
当我们知道循环结束的条件的时候,多数使用 while 循环
当我们明确知道会循环多少次的时候,优先使用 for 循环
指针和函数
求两个数和的函数
#include <stdio.h>
int main(int argc, char* argv[])
{
int sum(int a,int b);
int result=sum(3,4);
printf("result=%d\n",result);
//声明一个函数指针
int (*p2)(int x,int y);
//将一个函数赋值给函数指针
p2=sum;
int result1=p2(2,3);
printf("result1=%d\n",result1);
return 0;
}
int sum(int a,int b)
{
return a+b;
}
运行结果
函数名:代表函数的入口,也是函数的地址
函数指针定义的时候,就是将函数名换成( * 指针名 );
函数指针也叫做函数类型,函数指针可以指向同一种类型的所有函数
求两个数积的函数
#include "stdafx.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
int (*p2)(int x,int y);
int product(int m,int n);
//将一个函数赋值给函数指针
p2=product;
int j=p2(2,3);
printf("product=%d\n",j);
return 0;
}
int product(int m,int n)
{
return m*n;
}
运行结果
指针当作函数的参数,写一个交换两个数值的函数
#include "stdafx.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
void chang(int *p1,int *p2);
int c=3,d=4;
chang(&c,&d);
printf("c=%d,d=%d\n",c,d);
return 0;
}
//实参给形参传递地址
//指针当参数,传递的是地址
void chang(int *p1,int *p2)
{
int temp;
temp=*p1; //取内容,数值3
*p1=*p2;
*p2=temp;
}
//实参给形参只传递了数值
void chang1(int i,int j)
{
int temp;
temp=i;
i=j;
j=temp;
}
运行结果
参数地址传递示意图
End of File
行文过程中出现错误或不妥之处在所难免,希望大家能够给予指正,以免误导更多人,最后,如果你觉得我的文章写的还不错,希望能够点一下喜欢和关注,为了我能早日成为简书签约作者献上一发助攻吧,谢谢!^ ^