指针的指针,数组与指针,二维数组里指针的走位,爱心代码

题目:任意两个数,求之间的质数

#include<stdio.h>
void main()
{
    int i = 0,k = 0,m = 0,n = 0,j = 0;
    printf("请任意输入两位整数:\n");
    scanf("\n%d\n%d",&i,&j);
    getchar();
    printf("\n%d%d之间所有的质数有:",i,j);
    for(n = 1;n < j;n++)
    {
        for(m = 2;m < n;m++)
        {
            if(n % m == 0)
            {
                k = 0;
                break;
            }else{
                k = 1;
            }       
        }
        if(k == 1 && n >= i)
        {
            printf("\n%d",n);
        }
    }       
    getchar();
}

指向指针的指针,听起来就很绕有没有?

指针 是存地址的变量,是活的,它可以指向不同的地址。
地址 是内存分配的,是死的。

int *p = &a 等同于 int *p; p = &a, *p = a;
注意前后的区别,重点是“*“在定义和取值时的不同含义。
&与*

int *p;
p = &a;
&*p = &(*p) = &a;
&a = (&a) = *p = a;

定义时可以理解为“ * ”是指针标量的特有标志,“ * ”的数量可以理解为嵌套的层级,“ * ”越多层级越高,越靠外。

#include<stdio.h>
void main()
{
int a = 10;             //变量名a,变量地址&a,值10int *p = &a;            //变量名p,变量地址&p,值&a; 
int **p1 = &p;          //变量名p1,变量地址&p1,值&p;  p1就只指向指针变量的指针变量,所以它有两颗星。
printf("%d\t%d\t%d",&a,&p,&p1);    //4259004 4259008 4259000
printf("\n%d\t%d\t%d",a,p,p1);      //10 4259004 4259008
getchar();
}

指针类型和它要指向的变量或指针类型要一致
如果不一致,比如:
int 型的指针,指向一个char型的变量,就会出现有非目标储存区域被指到。
如果char型的指针,指向一个int型的变量,那么有会出现目标储存区域没有全部被指到。

指针的运算:

指针变量的值是所指向的变量的地址。,地址的加减形成指针的移动,指针的移动的最小单元取决于所指向的变量的类型。如果是int型则每次移动4个字节,chari型则移动一个字节。

一维数组演示指针移动的规律

int a[8] = {1,2,3,4,5,6,7,8};
int *p = &a[0];
那么:*(p+i) = a[i]

p++与(p++)等价

指针的比较

比较两个指针的大小实际上是比较两个指针指向的地址的前后,在内存中越靠后的地址越大。

指针与数组

指向数组元素的指针
int a[8];
int *p;
p = &a[0];
或者int *p = &a[0];
或者*p = a

通过指针引用多维数组

int a[3][4];
行指针没走一个就是一行,列指针走一个就是一个。
a[0] 代表第一行第一个
a[i] 代表第i + 1行第一个
a[0] + 1 代表第一行第二个
a[i]+j 代表第i+1行第j+1个,

代码演示
#include<stdio.h>
#include<windows.h>
void main()
{
    int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
    int *p;
    p = &a[0][0];
    while(1)
    {
        printf("%d\t",*p++); \\每秒钟指针的地址往后走一位
        Sleep(1000);
    }
    getchar();
}
结果显示,行走的路线是一行一行的走完,超出数组长度以后出现乱码。

接下来就有点绕了:

int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *p;
p = &a[0][0];

首先经过代码验证发现:
a/&a/*a, a[0]/&a[0]/a[0], p
这七个东西打印出来的结果是一毛一样的,都是数组第一个元素a[0][0]的地址。

接下来就要用指针进行风骚的走位了,注意规律:

  *(a+1)  = &a[1][0] 
  *( *(a+1)) = a[1][0] = 5
  *( *a+1) = a[0][1] = 2
  *( *(a+1) + 2) = a[1][2]

总结一下我的理解:
换行就是*(a + i)                    
对应的取值形式就是 *( *(a +i))

换列就是*a + i
对应的取值形式就是  *( *a + i)

即换行又换列就是*(a + i) + j
对应的取值形式就是*( *(a + i) + j)

取到值之后运算:*( *(a + i) + j) + k;

在一个a[3][4],这个数组中,* (a +2)+1与*a +7取到的地址是一样的,都是&a[2][1];
如果地址移动到数组范围以外,则出现不可预见的乱码。

打针:

第一步写好目标文件,属性为默认的.exe(应用程序)格式:

#include<stdio.h>
#include<windows.h>
void main()
{
    char name = 'Y';
    int hp = 1000;
    double money = 10000;
    printf("%x\t%x\t%x\n",&name,&hp,&money);
    while(1)
    {
        printf("\n我的名字:%c\t我的血量:%d\t我的钱:%f ",name,hp--,money--);
        Sleep(1000);
        }
}

第二步,新建一个项目,项目属性改为.dll(动态库),然后编写外挂程序:

通过指针更改内存值
#include<stdio.h>

_declspec(dllexport) go()
{
    char *p = (char *)0x2efb73;
    int *p1 = (int *)0x2efb64;
    double *p2 = (double *)0x2efb54;
    while(1)
    {
        *p  = 'Z'; 
        *p1 = 100;
        *p2 += 100;

    }
}

第三步:编写好以后生成解决方案,项目文件夹你就可以找到新生成的dll文件。
第四步:执行打针的动作,打开打针工具,找到正在运行的目标程序,添加dll文件,将加载函数名与挂程序的函数名改为一致。搞定。

今天是情人节,代码就是我的情人,献上“爱心”代码:

float h(float x, float z) {
    for (y = 1.0f; y >= 0.0f; y -= 0.001f)
        if (f(x, y, z) <= 0.0f)
            return y;
            return 0.0f;
}   

int main() {
    HANDLE o = GetStdHandle(STD_OUTPUT_HANDLE);
    _TCHAR buffer[25][80] = { _T(' ') };
    _TCHAR ramp[] = _T(".:-=+*#%@");

    for (t = 0.0f;; t += 0.1f) {
        int sy = 0;
        float s = sinf(t);
        float a = s * s * s * s * 0.2f;
        for (z = 1.3f; z > -1.2f; z -= 0.1f) {
            _TCHAR* p = &buffer[sy++][0];
            float tz = z * (1.2f - a);
            for (x = -1.5f; x < 1.5f; x += 0.05f) {
                float tx = x * (1.2f + a);
                float v = f(tx, 0.0f, tz);
                if (v <= 0.0f) {
                    float y0 = h(tx, tz);
                    float ny = 0.01f;
                    float nx = h(tx + ny, tz) - y0;
                    float nz = h(tx, tz + ny) - y0;
                    float nd = 1.0f / sqrtf(nx * nx + ny * ny + nz * nz);
                    float d = (nx + ny - nz) * nd * 0.5f + 0.5f;
                    *p++ = ramp[(int)(d * 5.0f)];
                }
                else
                    *p++ = ' ';
            }
        }

        for (sy = 0; sy < 25; sy++) {
            COORD coord = { 0, sy };
            SetConsoleCursorPosition(o, coord);
            WriteConsole(o, buffer[sy], 79, NULL, 0);
        }
        Sleep(33);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值