2020-12-01C/C++学习00
请注意,本文编写于 727 天前,最后修改于 704 天前,其中某些信息可能已经过时。

目录


指针

  1. 在哪里,指针变量存的值是当地址用的
  2. 是什么,解释方式

1.命名规范

c
int n = 999;

//命名可以分长短指针
int *pN = &n;

int *lpN = &n;

2.特点

简单粗暴

  1. 说去读谁就读谁
  2. 说去写谁就写谁

3.使用

c
# include <stdio.h>
# include <stdlib.h>
# include <string.h>


int main()
{
    int n = 999;
    int *pN = NULL;
   *pN = &n; //负责记录n的地址

    printf("%p\r\n",pN);     //直接访问,系统直接读取pN所在的地址的数据
    printf("%p\r\n",*pN");   //间接访问,系统通过指针调用pN所在的地址,之后再读取地址存贮的数据

    *pN = 666;               //两次访问
    pN[0] = 999;             //两次访问
    system("pause");
    return 0;
}

指针没有类型间的隐式转换,如果要转换需要强制转换

4.直接访问和间接访问

直接访问:
直接通过定义的变量来获取变量的数值
间接访问:
通过指针的形式,指向原来变量存储的值,同样也可以进行修改

5.运算法则

指针加减整型

结果为同类型指针常量

c
type *ptr = ...;
int n = ...;
ptr + n = (int)ptr + sizeof(type)*n;
        指针加整型,结果为同类型指针常量
        = (type *)((int)ptr + sizeof(type) * n)

加法:
  指针 + 整型 = (int)指针 + sizeof(指针类型)*整型值
    结果为同类型指针常量
减法:
  指针1(同类型) – 指针2(同类型) = ((int)指针1-(int)指针2)/sizeof(指针类型)
  相减后返回的类型是整型。

指针下标运算整型

c
对指针做下标运算,会发生间接访问
ptr[n] = (type *)((int)ptr + sizeof(type) * n)

int *p = NULL;
printf("%p\r\n",&p[8]);
((int)p + sizeof(int) * 8)
//00000020

&*互为逆运算
*&n == n
&*ptr == ptr

知识点

c
type *p1 = ...;
type *p2 = ...;

同类型相减得到整型常量
p1 - p2 = (int)p1 - (int)p2 / sizeof(type)

6.规范

  1. 指针任何时候都必须初始化NULL值,需要使用的时候在赋其他值。不能出现未知状态,禁止高空抛物
c
    int n = 999;
    int *pN = NULL;
    pN = &n;

7.指针与函数

c
# include <stdio.h>
# include <stdlib.h>
# include <string.h>

void swap(int *p1,int *p2)
{
    //间接访问才可以互换
    int nTmp = 0;
    nTmp = *p1;
    *p1 = *p2;
    *p2 = nTmp;
}

int main()
{
    int n = 999;
    int m = 666;
    swap(&n,&m);

    printf("%d\r\n",n);
    printf("%d\r\n",m);
    system("pause");
    return 0;
}

8.指针与数组

c
int a[5] = {0};
*p=&a[1];

引用一个数组元素可以有两种方法:
下标法,如a[i]指针法,如*(p+i)

9.题外话

c
十六进制浮点编码值
# include <stdio.h>
# include <stdlib.h>
# include <string.h>

int main()
{
    float f = 3.14f;
    int *p = NULL;
    p = (int *)&f;
    printf("%08x\r\n",*p);
    system("pause");
    return 0;
}
c
可变参数
# include <stdio.h>
# include <stdlib.h>
# include <string.h>


//必须是__cdecl,因为不知道有多少参数,没办法自己平栈
int __cdecl CalcSum(int n,...)
{
    int nSum = 0;
    int *p = NULL;
    p = &n;
    while(*p != 0)
    {
        nSum = nSum + *p;
        p++;
    }
    return nSum;
}

int main()
{
    printf("%d\r\n",CalcSum(1,2,3,4,0));
    printf("%d\r\n",CalcSum(1,2,0));
    printf("%d\r\n",CalcSum(1,2,3,0));

    system("pause");
    return 0;
}

va_list
VA_LIST是在C语言中解决变参问题的一组宏,所在头文件:# include <stdarg.h>,用于获取不确定个数的参数。

c
# include <stdio.h>
# include <stdlib.h>
# include <stdarg.h>



int __cdecl CalcSum(int first,...)
{
    int nSum = 0;
    int i = first;
    va_list marker; //int *p
    va_start(marker,first); //p = &first;
    while(i != -1)
    {
        nSum += i;
        i = va_arg(marker,int);  //i = *p++;
    }
    va_end(marker);
    return nSum;
}

int main()
{
    printf("%d\r\n",CalcSum(1,2,3,4,-1));
    printf("%d\r\n",CalcSum(1,2,-1));
    printf("%d\r\n",CalcSum(1,2,3,-1));

    system("pause");
    return 0;
}

10.指针与字符串

c
# include <stdio.h>
# include <stdlib.h>
# include <stdarg.h>

int main()
{
    char *psz = "HelloWorld!";      //常量区
    char szBuf[] = "HelloWorld!";   //栈

    szBuf[0] = 'h'; //可读写
    puts(szBuf);

    psz[0] = 'h';   //不可写
    puts(psz);

    system("pause");
    return 0;
}

本文作者:Na1r

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!