飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

楼主: Nisy

[C/C++] C语言随堂作业一(看过视频后望大家再写一遍并提交代码)

[复制链接]

该用户从未签到

发表于 2009-5-11 14:08:20 | 显示全部楼层
  1. /* Note:Your choice is C IDE */
  2. #include"stdio.h"
  3. #include"math.h"
  4. void main()
  5. {
  6. int i,j;
  7. for(i=-7;i<=7;i++)
  8. {
  9. for(j=-7;j<=7;j++)
  10. if(abs(i)+abs(j)==7)
  11. printf("*");
  12. else
  13. printf(" ");
  14. printf("\n");
  15. }
  16. }
复制代码

评分

参与人数 1飘云币 +200 收起 理由
Nisy + 200 多谢您的参与!

查看全部评分

PYG19周年生日快乐!

该用户从未签到

发表于 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");
        }
}

评分

参与人数 1飘云币 +80 收起 理由
Nisy + 80 多谢您的参与!

查看全部评分

PYG19周年生日快乐!

该用户从未签到

发表于 2009-5-11 16:55:24 | 显示全部楼层
楼上很多空心菱形很精简啊 ,向大家学习

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

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

sshot-1.gif

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

sshot-2.gif

它对应的十进制是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')

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

[ 本帖最后由 unpack 于 2009-5-11 17:04 编辑 ]
PYG19周年生日快乐!

该用户从未签到

发表于 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的话内存中的数据你让它是什么就是什么
  1. #include "stdio.h"
  2. #include <math.h>
  3. main()
  4. {
  5.     int i,j,N,F;
  6.    
  7.     printf("please input a int:");
  8.     scanf("%d",&N);
  9.     if (N % 2 == 0 )
  10.     {
  11.        N=N+1;
  12.       
  13.         goto ESLE;
  14.     }
  15.    else
  16.     {
  17. ESLE:         F = N/2;
  18.         for (i=0;i<N;i++)
  19.         {
  20.             for (j=0;j<=N;j++)
  21.             {
  22.             if (j == abs (F - i) || j == N - 1 - abs (F - i )) printf("*");
  23.             else if (j == N) printf("\n");
  24.             else printf(" ");
  25.          
  26.             }
  27.         }
  28.     }
  29.       getch();
  30. }
复制代码

[ 本帖最后由 飘之叶 于 2009-5-13 19:05 编辑 ]
PYG19周年生日快乐!

该用户从未签到

 楼主| 发表于 2009-5-11 19:14:52 | 显示全部楼层
原帖由 飘之叶 于 2009-5-11 17:52 发表
早上看第二次视频看懵了,刚才不知道怎么回事突然间理解

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



红色的地方写的好
PYG19周年生日快乐!
  • TA的每日心情
    开心
    2016-4-29 07:52
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2009-5-11 20:40:25 | 显示全部楼层
    提示: 作者被禁止或删除 内容自动屏蔽
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-5-11 20:47:43 | 显示全部楼层
    提示: 作者被禁止或删除 内容自动屏蔽
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-5-11 21:46:49 | 显示全部楼层
    #define H strlen(a)
    main()
    {
            char *a="ChinaPYG!";
                    //mov         dword ptr [ebp-4],offset string "ChinaPYG!"
                    //将字符串地址放入局部变量之中。所放的四个字节为从ebp-1到ebp-4
            int  *b=0;
                    //mov         dword ptr [ebp-8],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 [ebp-7]
                      //第一次循环结束跳转到这里,以后的每次循环都从这里开始。
                      //取b的一个字节到al
              add         al,1
                      //al自加1
              mov         byte ptr [ebp-7],al
                      //将自加结果放回b中
              movsx       esi,byte ptr [ebp-7]
                      //第一次直接跳到这里,ebp-7是取b的四字节中的一个字节
              mov         ecx,dword ptr [ebp-4]  
                      //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 [ebp-7]
                            //b放入edx中
                mov         eax,dword ptr [ebp-4]
                            //eax指向字符串
                movsx       ecx,byte ptr [eax+edx]
                            //以字符串地址作为基址,以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中所存储的一个字节。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-12-18 12:34
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 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 编辑 ]
    PYG19周年生日快乐!

    该用户从未签到

    发表于 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 编辑 ]
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表