* পিটিআর + = 1 এবং সিটিতে * পিটিআর ++ এর মধ্যে পার্থক্য


122

আমি সবেমাত্র সি পড়া শুরু করেছি এবং যখন ফাংশনটির প্যারামিটার হিসাবে পয়েন্টারটিতে পয়েন্টার পাস করার বিষয়ে একটি উদাহরণ করছিলাম তখন আমি একটি সমস্যা পেয়েছি।

এটি আমার নমুনা কোড:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int* allocateIntArray(int* ptr, int size){
    if (ptr != NULL){
        for (int i = 0; i < size; i++){
            ptr[i] = i;
        }
    }
    return ptr;
}

void increasePointer(int** ptr){
    if (ptr != NULL){
        *ptr += 1; /* <----------------------------- This is line 16 */
    }
}

int main()
{
    int* p1 = (int*)malloc(sizeof(int)* 10);
    allocateIntArray(p1, 10);

    for (int i = 0; i < 10; i++){
        printf("%d\n", p1[i]);
    }

    increasePointer(&p1);
    printf("%d\n", *p1);
    p1--;
    free(p1);
    fgets(string, sizeof(string), stdin);
    return 0;
}

সমস্যাটি 16 লাইনে ঘটে যখন আমি সংশোধন *ptr+=1করি *ptr++। প্রত্যাশিত ফলাফলটি পুরো অ্যারে এবং 1 নম্বর হওয়া উচিত তবে আমি *ptr++ফলাফলটি 0 ব্যবহার করি ।

+=1এবং এর মধ্যে কোনও পার্থক্য আছে কি ++? আমি ভেবেছিলাম যে উভয়ই একই রকম।


2
নোট করুন যে প্রদত্ত কোডটি আপনি ঘোষণা না করায় সংকলন করবে না string
স্পিক্যাট্রিক্স

6
অন্যান্য নোট: 1) allocateIntArrayএকটি খারাপ নাম কারণ এটি আপনাকে mallocফাংশন থেকে অ্যারে বলে মনে হচ্ছে , কিন্তু আপনি তা করেন না। আমি fillIntArrayপরিবর্তে প্রস্তাব । 2) আপনি এর রিটার্ন মান ব্যবহার করবেন না allocateIntArray। আমি আপনাকে রিটার্নের ধরনটি পরিবর্তন করতে পরামর্শ দিই void। 3) if (ptr != NULL)ফাংশন increasePointerথাকা উচিত নয় if (*ptr != NULL)? 4) cast mallocালাই অনিবার্য। উপরে সৌরভ এর মন্তব্য দেখুন। 5) এটি: for (int i = 0; i < 10; i++){ printf("%d\n", p1[i]); }এবং printf("%d\n", *p1); p1--;এটিকে আবদ্ধ করা দরকার if(p1 != NULL)। 6) string.hঅব্যবহৃত।
স্পিক্যাট্রিক্স

9
p+=1মত ++p, মত নয়p++
Kos

5
এই প্রশ্নের 4 বছর আগে জিজ্ঞাসা করা হল, হল ++, + + = 1 পয়েন্টার জন্য হিসাবে একই
Ren

3
@ren প্রায়, কিন্তু বেশ না। লিঙ্কযুক্ত প্রশ্নটি ডিপ্রেশন অপারেটরকে জড়িত করে না, যা এখানে ওপি'র ইস্যুটির ক্রুક્સ the
জেসন সি

উত্তর:


289

পার্থক্যটি অপারেটর অগ্রাধিকারের কারণে।

পোস্ট-ইনক্রিমেন্ট অপারেটরের ++অধিবেশন অপারেটরের চেয়ে বেশি অগ্রাধিকার রয়েছে *। সুতরাং *ptr++সমতূল্য*(ptr++) । অন্য কথায়, পোস্ট ইনক্রিমেন্ট পয়েন্টারটি পরিবর্তিত করে, এটি কী দেখায় তা নয়।

অ্যাসাইনমেন্ট অপারেটরের +=ডেরেফারেন্স অপারেটরের চেয়ে কম অগ্রাধিকার রয়েছে *, তাই *ptr+=1সমান (*ptr)+=1। অন্য কথায়, অ্যাসাইনমেন্ট অপারেটর পয়েন্টারটি নির্দেশ করে এমন মানটি পরিবর্তন করে এবং নিজেই পয়েন্টারটি পরিবর্তন করে না।


3
নতুনদের জন্য, একটি স্মৃতিসম্বন্ধীয় মধ্যে মিল হল *p++এবং *++p। পূর্ববর্তীগুলির অপারেটর নজিরটি স্পষ্ট, প্রাক্তনদের একটি।
ওয়াল্টার ট্রস

21

আপনার প্রশ্নের সাথে জড়িত 3 জন অপারেটরের অগ্রাধিকার ক্রমটি নিম্নলিখিত:

পোস্ট-ইনক্রিমেন্ট ++> ডেরেফারেন্স* > অ্যাসাইনমেন্ট+=

বিষয় সম্পর্কে আরও তথ্যের জন্য আপনি এই পৃষ্ঠাটি চেক করতে পারেন ।

একটি এক্সপ্রেশন পার্স করার সময়, কোনও অপারেটর যা কিছু সারিতে তালিকাভুক্ত থাকে তার নীচে আরও একটি সারিতে তালিকাভুক্ত যে কোনও অপারেটরের তুলনায় তার যুক্তিগুলির সাথে আরও শক্ত (যেমন বন্ধনী দ্বারা) আবদ্ধ হবে। উদাহরণস্বরূপ, প্রকাশ*p++ পার্স করা হয়েছে *(p++), যেমনটি নয় (*p)++

দীর্ঘ গল্প সংক্ষিপ্ত, *ptr+=1পোস্ট-ইনক্রিমেন্ট অপারেটর ব্যবহার করে এই অ্যাসাইনমেন্টটি প্রকাশ করার জন্য আপনাকে এই অপারেশনটিকে অগ্রাধিকার ++হিসাবে ডিটারেন্স অপারেটরের সাথে প্রথম বন্ধনী যুক্ত করতে হবে(*ptr)++


3
আকর্ষণীয়ভাবে, এটি বর্তমানে একমাত্র উত্তর যা সমাধান রয়েছে ... (* পিটিআর) ++
হাইড

7

ক্রমের ক্রম দেখানোর জন্য প্রথম বন্ধনী প্রয়োগ করি

a + b / c
a + (b/c)

এর সাথে আবার এটি করা যাক

*ptr   += 1
(*ptr) += 1

এবং আবার সঙ্গে

*ptr++
*(ptr++)
  • ইন *ptr += 1, আমরা আমাদের পয়েন্টার পয়েন্টের ভেরিয়েবলের মান বৃদ্ধি করি করে।
  • ইন *ptr++, আমরা আমাদের সম্পূর্ণ বিবৃতি (কোডের লাইন) শেষ হওয়ার পরে পয়েন্টারটি বৃদ্ধি করি এবং আমাদের পয়েন্টার পয়েন্টগুলিতে ভেরিয়েবলের একটি রেফারেন্স ফিরে পাই ।

পরেরটি আপনাকে এ জাতীয় কাজ করতে দেয়:

for(int i = 0; i < length; i++)
{
    // Copy value from *src and store it in *dest
    *dest++ = *src++;

    // Keep in mind that the above is equivalent to
    *(dest++) = *(src++);
}

এটি একটি সাধারণ পদ্ধতি যা srcঅন্য destঅ্যারেতে অ্যারে অনুলিপি করতে ব্যবহৃত হয় ।


"এবং আমাদের পয়েন্টার পয়েন্টগুলিতে ভেরিয়েবলের একটি রেফারেন্স ফিরিয়ে দিন" " সি রেফারেন্স নেই।
মাইলস রাউট

@ মাইলসআরট সম্ভবত এটি একটি ল্যাভেলু বলা আরও সঠিক হতে পারে? তবে জারগন যোগ না করে কীভাবে এটি রাখবেন তা আমি নিশ্চিত নই।
মতিন উলহাক

3

খুব ভাল প্রশ্ন।

কে অ্যান্ড আর "সি প্রোগ্রামিং ল্যাঙ্গুয়েজ" "5.1 পয়েন্টার এবং ঠিকানা" ", আমরা এর জন্য উত্তর পেতে পারি।

"অ্যানারি অপারেটরগুলি * এবং & গণিত অপারেটরগুলির চেয়ে আরও শক্তভাবে আবদ্ধ"

*ptr += 1      //Increment what ptr points to.

"ইউনিারি অপারেটররা * এবং ++ ডান থেকে বামে সহযোগী করে ।"

*ptr++        //Increment prt instead of what ptr point to.

// এটি * (পিটিআর ++) এর মতো কাজ করে।

সঠিক উপায়টি হ'ল:

(*ptr)++      //This will work.

এই প্রথম স্ট্যাক ওভারফ্লোতে আমি মন্তব্য করছি। আমি কোডটির ফর্ম্যাটটি আপডেট করেছি ^^ আপনার পরামর্শের জন্য ধন্যবাদ।
নিক.স্যাং

2

* পিটিআর + = 1: পিআরটি পয়েন্ট করে এমন বর্ধিত ডেটা। * পিটিআর ++: বৃদ্ধি পয়েন্টার যা পয়েন্টারটি নির্দেশ করে এমন ডেটার পরিবর্তে পরবর্তী মেমরি অবস্থানের দিকে নির্দেশ করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.