c语言指针

233 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

取地址运算

&——取地址运算符

  • scanf("%d",&i);里的&
  • 获得变量的地址,在c语言中,变量是放在内存里的,它的操作数必须是变量
  • int i; printf("%x",&i);
  • 地址的大小是否与int相同取决于编译器
  • int i; printf("%p", &i);
#include <stdio.h>

int main(void)
{
    int i;
    printf("0x%x\n",&i);
    
    return 0;
}

//结果:warning——类型不匹配
//输出结果:0xbff12d70
#include <stdio.h>

int main(void)
{
    int i;
    printf("%p\n",&i);
    
    return 0;
}
//输出结果:0xbff12d70  没有warning
#include <stdio.h>

int main(void)
{
    int i = 0;
    int p;
    p = (int)&i; //强制类型转换
    printf("0x%x\n",p);
    
    return 0;
}
//输出结果:0xbff12d70  没有warning
#include <stdio.h>

int main(void)
{
    int i = 0;
    int p;
    p = (int)&i; //强制类型转换
    printf("%lu\n", sizeof(int));
    printf("%lu\n", sizeof(&i));
    
    return 0;
}
/*结果:4
       4

以上是以32为架构转换的

#include <stdio.h>

int main(void)
{
    int i = 0;
    int p;
    p = (int)&i; //强制类型转换
    printf("0x%x\n", p);
    printf("%p\n", &i);
    
    return 0;
}
/*输出结果:0x5c961d28
           0x7fff5c961d28*/

#include <stdio.h>

int main(void)
{
    int i = 0;
    int p;
    p = (int)&i; //强制类型转换
    printf("%lu\n", sizeof(int));
    printf("%lu\n", sizeof(&i));
    
    return 0;
}
/*结果:4
       8

以上是64为架构

&不能取的地址

  • &不能对没有地址的东西取地址
    • &(a+b)?
    • &(a++)?
    • &(++a)?

试试这些&

  • 变量的地址
  • 相邻的变量的地址
  • &的结果的sizeof
  • 数组的地址
  • 数组单元的地址
  • 相邻的数组单元地址
#include <stdio.h>

int main(void)
{
    int i = 0;
    int p;
    
    printf("%p\n", &i);
    printf("%p\n", &p);
}
//0xbff81d6c 0xbff81d68

在十六进制中上述结果6c 68只差了4个单位,而int刚好是4位

c语言会把变量存到stack里从上往下分配

#include <stdio.h>

int main(void)
{
    int a[10];
    int b;
    printf("%p\n", &a);
    printf("%p\n", &a);
    printf("%p\n", &a[0]);
    printf("%p\n", &a[1]);
    
    return 0;
}
/*0xbff8dd44
  0xbff8dd44
  0xbff8dd44
  0xbff8dd48*/

指针😝

就是保存地址的变量

通常用p表示

int i; //定义一个整数型变量
int*p=&i;  //定义一个指针型变量p
int*  p,q; 
int   *p,q; //定义一个指针型变量p和一个整数型变量q

*表示p是一个指向int变量的指针变量

通常称为p指向i

综上,指针实质就是将i的地址给p

指针变量

变量的值是内存的地址

  • 普通变量的值是实际值
  • 指针变量的值则是变量的地址

作为参考的指针

  • void f(int*p)
  • 在被调用的时候得到某个变量的地址
  • 在函数内部可以通过指针访问外部变量
#include <stdio.h>
void f(int *p);
int main(void)
{
	int i= 6;
	printf("&i=%p\n",&i);
	f(&i);
	
	return 0;
}

void f(int *p)
{
	printf("p=%p\n",p);
}

访问那个地址上的变量

  • *是一个单目运算符,用来访问指针的值所表示的地址上的变量
  • 可以做左值,也可以做右值
    • 左值之所以叫左值(因为出现在赋值号左边的不是变量,而是值,是表达式计算的结果)
    • 与*p类似的还有数组

指针的运算符&*

互相反作用

*&ypter——>*(&ypter)——>*(yptr的地址)——>得到那个地址上的变量——>ypter

&*yptr——>&(*yptr)——>&(y)——>得到y的地址,也就是yptr——>yptr