【问题标题】:Why is *randNum being incremented?为什么 *randNum 会递增?
【发布时间】:2013-07-29 12:50:07
【问题描述】:

请不要对这个问题投反对票,我意识到它并不过分具体,但这正是我的问题。我知道每个命令在我的代码中的作用,我只是不知道它们存在的原因。这非常难以搜索答案,因为我的问题主要与我自己的程序有关。抱歉,如果仍然无法回答,我会努力改进我未来的问题:)。

我需要编写一个可以跨共享内存进行通信的程序,轮流创建和删除进程。我试图理解我得到的那段代码,特别是下面的那段代码。在最底部,我包含了整个生产者代码,以防它帮助任何人回答我的问题。

问题:为什么 *randNum 增加超过 101 时,它打印输出的条件是等于 101?

这是否暗示消费者必须更改位置 *randNum 中包含的值才能满足条件?

for(A = 0; A < size; A++)    // for loop to reset all priority values so that they are clear to be used in the next set
    {
        *randNum = 101;
        *randNum++;
    }

稍后的 if 命令:

if(*randNum == 101)
                    {
                        *randNum = rand() % (100 - 1) + 1;
                        *pidNum = getpid();

                        printf("priority: %d Process ID: %d \n", *randNum, *pidNum);

                        x = 1;
                    }

正如承诺的那样,下面的完整程序用于完成目的(试图让您更轻松并避免提问;也提供上下文)

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>


void shm2sz(int size);

int main(int argc, char *argv[])


{
    int shmid, A, B, count, *shm, *randNum, *pidNum, pid, *memSig;

    key_t key;

    int size = atoi(argv[1]);

    int shmsz = (size * 2) + 1;  // declaring size of shared mem to be twice the size of user input, + 1 for owner ID

    int x = 0;

    int noToCreate = atoi(argv[2]);

    shm2sz(shmsz);
    key = 2060;        // Identifier key for SharedMem

    shmid = shmget(key, shmsz, IPC_CREAT | 0666);  //creating Sharedmem

    if(shmid < 0)   // variable if sharedmem is less than 0, print error.

            {
                    perror("shmget");    // eror mesage print
                    exit(1);
            }

    shm = shmat(shmid, NULL, 0);    //Attach to shared mem, if fails.. proceed with error message

    if(shm == (int *) -1)   // eror message

        {
                perror("shmat");
                exit(1);
        }


    randNum = shm;         // declare randNum equal to shm

    pidNum = shm + size;   // set pid to the first bit of the second part of the shared mem

    memSig = shm + shmsz;  // set memsig as final value in shared mem

    *memSig = 0;

    for(A = 0; A < size; A++)    // for loop to reset all priority values so that they are clear to be used in the next set
    {
        *randNum = 101;
        *randNum++;
    }

    count = 0;      // set count back to 0

    randNum = shm;              //check randNum equal to shm
    pidNum = shm + size;

    while(*memSig != 2)
    {
        while(*memSig == 1)   // set memsignature to sleep while..
        {
            sleep(1);
        }

        for(B = 0; B < noToCreate; B++)     
        {
            pid = fork();

            if(pid == -1)
            {
                perror("Error forking");
                exit(1);
            }
            else if(pid > 0)
            {
                wait(0);
            }
            else
            {
                srand(getpid());

                while(x == 0)
                {
                    if(*randNum == 101)
                    {
                        *randNum = rand() % (100 - 1) + 1;
                        *pidNum = getpid();

                        printf("priority: %d Process ID: %d \n", *randNum, *pidNum);

                        x = 1;
                    }
                    else
                    {
                        *randNum++;
                        *pidNum++;
                    }
                }
                exit(0);
            }
        } /* Closes main for loop */

        if(*memSig == 0)
        {
            *memSig = 1;
        }
    } /* Closes main while loop */
}

void shm2sz(int size)
{
    int shmid, *shm2;
    key_t key;

    key = 9876;

    shmid = shmget(key, 2, IPC_CREAT | 0666);

    if(shmid < 0)
    {
        perror("shmget2");
        exit(1);
    }

    shm2 = shmat(shmid, NULL, 0);

    if(shm2 == (int *) -1)
    {
        perror("shmat2");
        exit(1);
    }

    *shm2 = size;
}

【问题讨论】:

  • 使用调试器(如gdb)来了解程序的行为;用例如编译它gcc -Wall -g...

标签: c unix ipc consumer producer


【解决方案1】:

后缀递增运算符的operator precedence 高于指针取消引用运算符。这意味着*randNum++实际上增加了指针randNum。

如果你想增加randNum所指向的值,你必须使用括号:

(*randNum)++;

【讨论】:

  • 还有(*pidNum)++; :)
  • 啊,这是非常微妙的区别:)。谢谢!这是否意味着如果是 (*randNum)++,则在 for 循环的一个循环之后指向的值将是 102?相反,这是否意味着 randNum++ 在一个周期后不再指向 101,而是指向 101 之后的任何值(不是 102)?
  • @user2618840 两个问题都是。
  • 好的,那么for循环将地址中的101设置为0到size? *randNum = 101 *randNum++ = 101 *randNum+2 = 101 等等
  • @user2618840 可以,但不需要将赋值和增量分开:*randNum++ = 101; 就足够了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 2019-09-28
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多