杨家将 发表于 2009-5-11 14:08:20

/* Note:Your choice is C IDE */
#include"stdio.h"
#include"math.h"
void main()
{
int i,j;
for(i=-7;i<=7;i++)
{
for(j=-7;j<=7;j++)
if(abs(i)+abs(j)==7)
printf("*");
else
printf(" ");
printf("\n");
}
}

crackiss 发表于 2009-5-11 15:05:20

#include"stdio.h"
#include"math.h"
void main()
{
        int i,j,n;
        scanf("%d",&n);

        for(i=-(n-1)/2;i<=(n-1)/2;i++)
        {
                for(j=-(n-1)/2;j<=(n-1)/2;j++)
                {
                        if(abs(i)+abs(j)==(n-1)/2)
                        {
                                printf("*");
                        }
                        else
                        {
                                printf(" ");
                        }
                }
                printf("\n");
        }
}

unpack 发表于 2009-5-11 16:55:24

楼上很多空心菱形很精简啊 ,向大家学习

以下是对那个"变量都一样"的代码的自己的一点分析,不知道这样分析的对不对,不对之处还望指出
从没有见过这样来写,跟Nisy学到很多

int *b=x   其中x为某一个数字
int在内存中占两个字节,且以二进制存放,比如数字10,在内存中存放为



此时内存给它分配的空间就会有连个地址,设为1234、1235,那么00001010对应的地址应该就是1234了
当(char *)&b,因为char值占一个字节,所以它取的地址是1234,而(char *)&b+1取的就是下一个地址,也就是1235了,所以就*((char *)&b+1)就能理解为1235这个地址所对应的值,在上面数字10中对应的1235对应的值为0,即程序从第0位开始取a中的字符。所以整个程序可以这样理解#include "stdio.h"
#include "string.h"
void main()
{
        int i;
        char a[]="ChinaPYG!";
        for(i=0;i<strlen(a);i++)
                printf("%c",*(a+i));/*或则改为printf("%c",a);*/
        printf("\n");
}当我们要第1位开始取值,把int *b=x中的值就应该下面的改法,看表



它对应的十进制是256,此时如果取地址1235的值,对应就是1了。
所以,只要更改x的值为256的倍数,就可以从第多少位开始取值了,而在两个相邻倍数中间的值跟上个倍数取得的一样。

int*b=x    其中(x<256),则输出结果为:ChinaPYG!
int*b=256;   则输出结果为:hinaPYG!    在256—512之间的值,运行的结果跟这个一样。
int*b=512;   则输出结果为:inaPYG!
int*b=768;   则输出结果为:naPYG!
int*b=1024;   则输出结果为:aPYG!
……
int*b=2048;   则输出结果为:!
int*b=2304;   则输出结果为:(什么也没有!后面没有了,为'\0')

而如果改成#include "stdio.h"
#include "string.h"
#define H strlen(a)
main()
{
      char *a="ChinaPYG!";
      int*b=0;
      for( ; *((char *)&b) < H ; (*((char *)&b))++)
      printf("%c",*(a + *((char *)&b)));
}只要改*b=x中的x值就行了,而这样的话,就只要是往上加1就行了,比如要从第0位开始取,那么x等于0,从第一位开始取,x=1,依次下去就行

[ 本帖最后由 unpack 于 2009-5-11 17:04 编辑 ]

飘之叶 发表于 2009-5-11 17:52:25

代码的理解

早上看第二次视频看懵了,刚才不知道怎么回事突然间理解

/*#define H strlen(a)                //这个是错误的。
main()
{
      char *a="ChinaPYG!";
      char*b=0;                 // &b+2的地址超过了所分配的空间,导致错误,
                              //总之使用是不可以超过所分配的空间即可
                              //因为 char *b 等类型都是2个字节,因此加1不超过它的范围                        //加1实际上是地址加1,只要不超过所申请(定义)的空间都是可以的
      for(*((int *)&b+2)=0 ; *((int *)&b+2) < H ; (*((int *)&b+2))++)
      printf("%c",*(a + (*((int *)&b+2))));
}
*/
/#define H strlen(a)//这个也是正确的
main()
{
      char *a="ChinaPYG!";
      char *b=0;
      for(*((int *)&b)=0 ; *((int *)&b) < H ; (*((int *)&b))++)
      printf("%c",*(a + (*((int *)&b))));
}
*/

总结:
最关键的是空间,只要你有空间就OK了。NISY的话内存中的数据你让它是什么就是什么#include "stdio.h"
#include <math.h>
main()
{
    int i,j,N,F;
   
    printf("please input a int:");
    scanf("%d",&N);
    if (N % 2 == 0 )
    {
       N=N+1;
      
      goto ESLE;
    }
   else
    {
ESLE:         F = N/2;
      for (i=0;i<N;i++)
      {
            for (j=0;j<=N;j++)
            {
            if (j == abs (F - i) || j == N - 1 - abs (F - i )) printf("*");
            else if (j == N) printf("\n");
            else printf(" ");
         
            }
      }
    }
      getch();
}

[ 本帖最后由 飘之叶 于 2009-5-13 19:05 编辑 ]

Nisy 发表于 2009-5-11 19:14:52

原帖由 飘之叶 于 2009-5-11 17:52 发表 https://www.chinapyg.com/images/common/back.gif
早上看第二次视频看懵了,刚才不知道怎么回事突然间理解

/*#define H strlen(a)                //这个是错误的。
main()
{
      char *a="ChinaPYG!";
      char*b=0;                 // &b+2的地址超过了所分配的空间,导致错误 ...


红色的地方写的好

HDd1145 发表于 2009-5-11 20:40:25

a0094yan 发表于 2009-5-11 20:47:43

网际座山雕 发表于 2009-5-11 21:46:49

#define H strlen(a)
main()
{
      char *a="ChinaPYG!";
                //mov         dword ptr ,offset string "ChinaPYG!"
                //将字符串地址放入局部变量之中。所放的四个字节为从ebp-1到ebp-4
      int*b=0;
                //mov         dword ptr ,0
                //将0放入局部变量2中,该地址里面内容为0,作为指针指向地址0
                //所放的位置为从ebp-5到ebp-8,四个字节。
      for( ; *((char *)&b+1) < H ; (*((char *)&b+1))++)
                /*
          jmp         main+30h (00401040)
          mov         al,byte ptr
                  //第一次循环结束跳转到这里,以后的每次循环都从这里开始。
                  //取b的一个字节到al
          add         al,1
                  //al自加1
          mov         byte ptr ,al
                  //将自加结果放回b中
          movsx       esi,byte ptr
                  //第一次直接跳到这里,ebp-7是取b的四字节中的一个字节
          mov         ecx,dword ptr
                  //ebp-4保存的是字符串地址,放入ecx中
          push      ecx
                  //ecx存入堆栈
          call      strlen (00401120)
                  //获得字符串长度
          add         esp,4
                  //strlen 由调用函数来恢复堆栈esp+4,使堆栈平衡
          cmp         esi,eax
          jae         main+5Fh (0040106f)
                  //esi如果大于等于eax,eax=字符串长度。就跳走,跳到的位置就是程序结束。否则,继续向下执行。
                  */
      printf("%c",*(a + *((char *)&b+1)));
                /*
            movsx       edx,byte ptr
                        //b放入edx中
            mov         eax,dword ptr
                        //eax指向字符串
            movsx       ecx,byte ptr
                        //以字符串地址作为基址,以b作为偏移,取一个字节,放入ecx中。
            push      ecx
            push      offset string "%c" (0042201c)
            call      printf (004010a0)
                        //调用函数输出这一个字节。
            add         esp,8
                        //恢复堆栈
            jmp         main+28h (00401038)
                        //跳转到前面
                */
               
               
}

总结:关键是这句*((char *)&b+1),b本身就是一个指针,这句,取了b的地址,也就是堆栈中的地址,我的是0012ff78,
然后,强制转换0012ff78为字符类指针,大家都知道,字符类型指针指向的乃是一个字节,
所以,此时(char *)&b指向0012ff78这个地址的一个字节,该字节在堆栈中,然后是(char *)&b+1
该指针上移一位,指向0012ff79,因为内存是由高到底分配的,所以说是上移。
最后是一个取内容的“*”操作,取出0012ff79所存储的一个字节,也就是ebp-7中所存储的一个字节。

qifeon 发表于 2009-5-11 22:16:28

#define H strlen(a)                                        //宏定义,H为字符串型指针a的长度
main()
{
      char *a="ChinaPYG!";                                 //定义a为指向 "ChinaPYG!"的指针
      int*b=0;                                           // 定义整型指针b,其实就是开辟2个字节空间,并初始化为0。
      for( ; *((char *)&b+1) < H ; (*((char *)&b+1))++)    // *((char *)&b+1)相当于一个变量,指向b的第二个字节,即初始值为0。
      printf("%c",*(a + *((char *)&b+1)));               //逐位打印 "ChinaPYG!"中的字符

可以稍微修改下,实质是一样的。
*((char *)&b+1)改为*((char *)&b)

#define H strlen(a)
main()
{
      char *a="ChinaPYG!";
      int*b=0;
      for( ; *((char *)&b) < H ; (*((char *)&b))++)
      printf("%c",*(a + *((char *)&b)));
}
这里利用了指针的指针,变量定义的很巧妙。

打印菱形
#include"stdio.h"
#include"math.h"
void main()
{
int i,j,N;
scanf("%d",&N);
for(i=-(N-1)/2;i<=(N-1)/2;i++)
{
for(j=-(N-1)/2;j<=(N-1)/2;j++)
if(abs(i)+abs(j)==(N-1)/2) printf("*");
else printf(" ");
printf("\n");
}
}

[ 本帖最后由 qifeon 于 2009-5-11 23:24 编辑 ]

网际座山雕 发表于 2009-5-11 22:52:58

// test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"
#include "string.h"
#include "math.h"

int main(int argc, char* argv[])
{
    int temp;
        int i;
        int j;
        scanf("%d",&temp);

    for (i=1;i<(temp+1)/2;i++)
    {
                printf(" ");
    }
        printf("*\n");



   
    for (j=1;j<temp-1;j++)
        {
                for (i=1;i<temp+1;i++)
                {

                        if (j== abs((temp+1)/2-i) || j-(temp+1)/2==(temp+1)/2-abs((temp+1)/2-i)-2)
                        {
                                printf("*");
                        }
                        else
                        {
                                printf(" ");
                        }
       }
                printf("\n");
        }


    for (i=1;i<(temp+1)/2;i++)
    {
                printf(" ");
    }
        printf("*\n");
        return 0;
}


该程序在vc6下编译通过。

[ 本帖最后由 网际座山雕 于 2009-5-11 22:54 编辑 ]
页: 1 [2] 3 4 5
查看完整版本: C语言随堂作业一(看过视频后望大家再写一遍并提交代码)