热门搜索 :
考研考公
您的当前位置:首页正文

C_09 指针

来源:东饰资讯网

字节:是内存中最小的储存单位,不同的数据类型在内存中占的大小也不一样

内存地址:为了正确的访问内存单元上的数据,我们人为的给每个内存起上编号,这个编号就是内存的地址

访问数据的方式:
直接访问方式—>通过变量名
间接访问方式—>通过地址访问

指针是一个地址

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

行文过程中出现错误或不妥之处在所难免,希望大家能够给予指正,以免误导更多人,最后,如果你觉得我的文章写的还不错,希望能够点一下喜欢关注,为了我能早日成为简书签约作者献上一发助攻吧,谢谢!^ ^

Top