题目:任意两个数,求之间的质数
#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,值10;
int *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);
}
}