C语言指针

本文详细介绍了指针的基础概念、定义、内存占用、操作符*和&的应用,以及指针与一维数组的关系。同时对比了sizeof和strlen在计算内存大小和字符串长度上的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、指针

1.1指针的相关概念、

指针:指向变量地址的类型

指针变量:指向变量地址的变量

地址:内存单元的编号就是地址

1.2指针的定义格式

变量类型  *变量名;

void  *;万能指针

1.3指针占用内存的大小

在32位系统上指针占4个字节

64位系统上指针占8个字节

1.4指针相关的*和&(取址)符号

&:获取变量的地址

*:代表取地址中的内容,定义的时候char  *p中的*只起到一个标识的作用,表示p是一个指针

1.5指针的基本用法

向地址中写入值

unsigned  int  *p = (unsigned  int  *)地址;#用强制类型转换将地址转换为和指针相同的类型,

*p  =  新的值

eg:

向0xaabbccdd地址中写入0x12345678的值。

unsigned int *p = (unsigned int *)0xaabbccdd;

*p = 0x12345678;

1.6指针加1和减1问题

#include <my_head.h>

int main(int argc, const char *argv[])
{
    int a = 10;
    int *p = NULL;
    p = &a;
    *p = 50;
    printf("p+1 = %p, &a = %p\n", p+1 , &a);

    return 0;
}

运行结果:

linux@ubuntu:~/DC101/01drivers/0329$ gcc main.c 
linux@ubuntu:~/DC101/01drivers/0329$ ./a.out 
p+1 = 0x7ffdd2831510, &a = 0x7ffdd283150c
linux@ubuntu:~/DC101/01drivers/0329$ 

0x10-0x0c = 0x04

// 指针加1移动的字节数,等于它指向类型所占的字节数
    // char *p; //p+1移动1字节
    // int *p; //p+1移动4字节
    // short *p; //p+1移动2字节
    // long *p; //p+1移动8字节
    printf("p-1 = %p,&a = %p\n", p - 1, &a);
    // 指针减1移动的字节数,等于它指向类型所占的字节数
    // char *p; //p-1移动1字节
    // int *p; //p-1移动4字节
    // short *p; //p-1移动2字节
    // long *p; //p-1移动8字节

1.7指针相减

#include <my_head.h>

int main(int argc, const char *argv[])
{
    int a = 10;
    int *p = NULL;
    p = &a;
    *p = 50;

    long b = 40;
    long *q = NULL;
    q = &b;
    *q = 80;

    printf("(p+1) - p = %ld\n", (p+1) - p);
    printf("(long)(p+1) - (long)p = %ld\n", (long)(p+1) - (long)p);
    printf("(q+1) - q = %ld\n", (q+1) - q);
    return 0;

运行结果:

linux@ubuntu:~/DC101/01drivers/0329$ gcc main.c 
linux@ubuntu:~/DC101/01drivers/0329$ ./a.out 
(p+1) - p = 1
(long)(p+1) - (long)p = 4
(q+1) - q = 1

在 C 语言中,指针之间的差值计算通常用于计算两个指针之间相隔的元素个数,而不是直接得到字节偏移量。指针相减的结果是一个整数值,表示两个指针之间相隔的元素个数,而不是字节偏移量。

二、指针和一维数组之间的关系

int  arr[3] = {111, 222, 333}

arr[0]: 

&arr[0]: 

arr: 

&arr:

arr[0]+1: 

&arr[0]+1: 

arr + 1: 

&arr + 1: 

arr[0] ++: 

&arr[0] ++: 

(&arr[0])++: 

arr ++:

&arr ++: 

(&arr)++:

arr[0]:第0个元素,它的类型是int,arr[0]是变量(arr[0]++)。

&arr[0]:对第0个元素取地址,它的类型是(int *),它是一个常量不能((&arr[0])++)

arr:它是一维数组的首地地址,它的指针类型是(int *),它是一个常量不能(arr++)。

&arr:对整个数组取地址,它的指针类型是(int (*)[3] ),它是一个常量((&arr)++).

arr[0]+1:将arr[0]的值取出和1做加法运算,结果是112.

&arr[0]+1:移动了4字节(int)的大小,(int *)

arr+1:移动了4字节(int)的大小,(int *)

&arr+1:移动了12字节(int [3])的大小,(int (*)[3])

arr[0]++:相当于是让第0个元素的值加1,赋值给了arr[0]

&arr[0]++:错误写法,常量不能取地址

(&arr[0])++:错误写法,常量不能自加

arr++:错误写法,常量不能自加

&arr++:错误写法,常量不能取地址

(&arr)++:错误写法,常量不能自加

int  a  =  10; &a  =  0x111;

int  *p  =  &a;

p: 

*p: 

&p: 

p+1: 

*p+1:

&p + 1:

p++: 

*p++: 

(*p)++: 

&p++: 

(&p)++: 

p:指针变量,它的类型是(int *)

*p:取地址中的内容,它的类型是(int),它是变量可以自加((*p)++)

&p:取指针变量p的地址,它类型是(int **),它是常量

p+1:移动了4字节,移动了(int)大小

*p+1:取出p指向内存中的数值,然后加了1,内存中的数值没有改变

&p+1:移动了8字节,移动了(int *)大小

p++:移动了4字节,指向了下一个int变量的地址

*p++:相当于取出*p,然后p++,p指向下一个int变量的地址。(p是地址变量,p++是地址常量,可以对它取*)

(*p)++:相当于让p指向内存中的值做了自加1的操作。

&p++:错误写法,常量不能取地址(p是地址变量,p++是地址常量,常量不能取地址)

(&p)++:错误写法,常量不自加

指针类型相同,指针加1移动大小也相同,此时可以直接划等号

int arr[3] = {111,222,333};

int *p;

p = arr;

p = &arr[0];

arr[i]<=>*(arr+i)<=>*(p+i)<=>p[i]

三、sizeof与srlen有什么区别

  1. sizeof是关键字,而strlen是函数。
  2. sizeof是求类型所占内存的大小,strlen求字符数组中字符的个数,strlen使用的时候必须有'\0'。
  3. sizeof计算字符串长度会加 ’\0‘

char arr[] = "hello";

sizeof(arr) = 6

strlen(arr) = 5

char arr[100] = "hello";

sizeof(arr) = 100

strlen(arr) = 5

char arr[] = {'h','e','l','l','o'};

sizeof(arr) = 5

strlen(arr) = 大小不能确定,没有'\0'

int arr[10] = {1,2,3,4,5,6,7,8,9,10};

sizeof(arr) = 40;

strlen((char *)arr) = 1

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值