উদ্দেশ্য-সিতে # ইম্পোর্ট এবং # অন্তর্ভুক্তের মধ্যে পার্থক্য কী?


384

অবজেক্টিভ-সিতে # ইম্পোর্ট এবং # অন্তর্ভুক্তের মধ্যে পার্থক্যগুলি কী এবং এমন কোনও সময় রয়েছে যেখানে আপনার একে অপরকে ব্যবহার করা উচিত? একজনকে অবহেলা করা হয়?

আমি নীচের টিউটোরিয়ালটি পড়ছিলাম: http://www.otierney.net/objective-c.html#preamble এবং # গুরুত্বপূর্ণ এবং # অন্তর্ভুক্ত সম্পর্কে এর অনুচ্ছেদটি নিজের বিরোধিতা বলে মনে হচ্ছে বা কমপক্ষে অস্পষ্ট।

উত্তর:


341

# অন্তর্ভুক্তির উন্নত সংস্করণ হিসাবে # ইমপোর্ট নির্দেশিকাটি উদ্দেশ্য-সিতে যুক্ত করা হয়েছিল। এটির উন্নতি হয়েছে কি না, তা এখনও বিতর্কের বিষয়। # আইম্পোর্টটি নিশ্চিত করে যে কোনও ফাইল কেবল একবার অন্তর্ভুক্ত করা হয়েছে যাতে আপনার পুনরাবৃত্তির সাথে কোনও সমস্যা না থাকে। যাইহোক, বেশিরভাগ ভদ্র হেডার ফাইলগুলি যেকোন উপায়ে এগুলি থেকে নিজেকে রক্ষা করে, তাই এটি আসলে কোনও উপকারের মতো নয়।

মূলত, আপনি কোনটি ব্যবহার করতে চান তা সিদ্ধান্ত নিতে হবে। আমি অবজেক্টিভ-সি জিনিসগুলির (যেমন শ্রেণির সংজ্ঞা এবং এর মতো) জন্য # শিরোনামগুলি প্রবণতা এবং আমার প্রয়োজন এমন স্ট্যান্ডার্ড সি জিনিসগুলি অন্তর্ভুক্ত করে। উদাহরণস্বরূপ, আমার উত্স ফাইলগুলির মধ্যে একটি এর মতো দেখতে পারে:

#import <Foundation/Foundation.h>

#include <asl.h>
#include <mach/mach.h>

63
এমনকি শিরোনামের ফাইলগুলিতে রক্ষীদের অন্তর্ভুক্ত থাকলেও, আপনি # অন্তর্ভুক্ত ব্যবহার করলে সংকলনের সময় একটি পারফরম্যান্স হিট হয় - সংকলকটি অবশ্যই অন্তর্ভুক্ত গার্ডদের লক্ষ্য করার জন্য প্রতিটি শিরোনাম ফাইলটি খুলতে হবে।
ম্যাট ডিলার্ড

4
শিরোনাম রক্ষক একটি প্রিপ্রোসেসর নির্দেশিকা যা নিশ্চিত করে যে একটি শিরোনাম কেবল একবার উত্স ফাইলে অন্তর্ভুক্ত করা হয়েছে।
জেসন কোকো

8
আমি মনে করি যে # ইম্পোর্টটি আসলে জিসিসি দ্বারা সংযোজন, উদ্দেশ্য-সি দ্বারা নয়। আপনি যতক্ষণ না জিসিসি (বা কলঙ্ক) দিয়ে সংকলন করেন ততক্ষণ আপনি এটি ও-ওজেসি ভাষাগুলিতে ব্যবহার করতে পারেন
ডেভ দেলং

33
@ ডেভ - # ইম্পোর্ট প্রিপ্রোসেসরটির সাথে একটি উদ্দেশ্য-সি সংযোজন। জিসিসি কেবল এটি সি এবং সি ++ উত্স ফাইলগুলিতে সমর্থন করে, যদিও তারা আনুষ্ঠানিকভাবে এটি বহনযোগ্য, traditionalতিহ্যবাহী শিরোলেখরক্ষীদের পক্ষে সি বা সি ++ এ ব্যবহার না করার পরামর্শ দেয়। সমস্ত অবজেক্টিভ-সি প্রিপ্রোসেসরগুলিতে অবশ্যই # আইপোর্ট অন্তর্ভুক্ত করা উচিত।
জেসন কোকো 4

13
শিরোনাম রক্ষী হয় যেখানে আপনি শীর্ষে যুক্ত হন: #ifndef myheader #define myheader ... এর পরে শিরোনাম কোডটি ...#endif
টিম

358

প্রিপ্রোসেসর সম্পর্কিত অনেক বিভ্রান্তি আছে বলে মনে হচ্ছে।

সংকলক যখন এটি দেখে তখন এটি কী করে #includeযে এটি সেই লাইনটি অন্তর্ভুক্ত ফাইলগুলির বিষয়বস্তুর সাথে প্রতিস্থাপন করে, কোনও প্রশ্ন জিজ্ঞাসা করা হয়নি।

সুতরাং আপনার যদি a.hএই বিষয়বস্তুগুলির সাথে কোনও ফাইল থাকে:

typedef int my_number;

এবং b.cএই বিষয়বস্তু সহ একটি ফাইল :

#include "a.h"
#include "a.h"

ফাইলটি b.cসংকলনের আগে প্রিপ্রসেসর দ্বারা অনুবাদ করা হবে

typedef int my_number;
typedef int my_number;

টাইপটি my_numberদু'বার সংজ্ঞায়িত করার কারণে এটি একটি সংকলক ত্রুটির ফলস্বরূপ । সংজ্ঞা একই হলেও এটি সি ভাষা দ্বারা অনুমোদিত নয়।

যেহেতু একটি শিরোনাম প্রায়শই একাধিক স্থানে ব্যবহৃত হয় রক্ষকরা সাধারণত সিতে ব্যবহৃত হয় এটি এরকম দেখাচ্ছে:

 #ifndef _a_h_included_
 #define _a_h_included_

 typedef int my_number;

 #endif

b.cপ্রিপ্রোসেসড হওয়ার পরে ফাইলটিতে এখনও শিরোনামের পুরো বিষয়বস্তু থাকবে twice তবে দ্বিতীয় উদাহরণটিকে উপেক্ষা করা হবে কারণ ম্যাক্রো _a_h_included_ইতিমধ্যে সংজ্ঞায়িত করা হত।

এটি সত্যই ভাল কাজ করে, তবে দুটি ত্রুটি রয়েছে। সবার আগে অন্তর্ভুক্ত রক্ষীদের লিখতে হবে, এবং ম্যাক্রোর নাম প্রতিটি শিরোনামে আলাদা হতে হবে। এবং দ্বিতীয়ত সংকলকটিতে এখনও শিরোনামের ফাইলটি সন্ধান করা এবং এটি অন্তর্ভুক্ত হওয়ার সাথে সাথে এটি পড়তে হবে।

অবজেক্টিভ-সিতে #importপ্রিপ্রসেসর নির্দেশাবলী রয়েছে (এটি কিছু সংকলক এবং বিকল্পগুলির সাথে সি এবং সি ++ কোডের জন্যও ব্যবহার করা যেতে পারে)। এটি প্রায় একই রকম করে #includeতবে এটি অভ্যন্তরীণভাবে নোট করে যে কোনও ফাইলটি ইতিমধ্যে অন্তর্ভুক্ত করা হয়েছে। #importলাইন শুধুমাত্র প্রথম সময় এটি সম্মুখীন হয় নামে ফাইলের বিষয়বস্তু দ্বারা প্রতিস্থাপিত হয়। প্রতিবারের পরে এটি কেবল উপেক্ষা করা হবে।


4
এটি গৃহীত উত্তর অপেক্ষা উত্তম উত্তর। @ গিল, আপনার গ্রহণযোগ্য উত্তরটি পরিবর্তন করা উচিত।
Nguyen মিন বিন

5
7000 লাইন টেমপ্লেট শিরোনাম ফাইলটিতে 4 #includeটি পরিবর্তন করার পরে #import, সংকলন এবং এক্সকোড ইন্টেলিজেন্স প্রতিক্রিয়াশীলতার মধ্যে একটি লক্ষণীয় পারফরম্যান্স উন্নতি হয়েছে। (আমি মনে করি আমি এটি কল্পনা করছি না)
বোবোবো

62

আমি জেসনের সাথে একমত

আমি এটি করতে গিয়ে ধরা পড়েছি:

#import <sys/time.h>  // to use gettimeofday() function
#import <time.h>      // to use time() function

জিএনইউ জিসিসি-র জন্য, এটি অভিযোগ করে চলেছে যে সময় () ফাংশনটি সংজ্ঞায়িত হয়নি।

তারপরে আমি # ইম্পোর্টকে # অন্তর্ভুক্তিতে পরিবর্তন করেছি এবং সব ঠিক আছে।

কারণ:

আপনি #import <sys / time.h> এ:
    <sys / time.h> এ শুধুমাত্র একটি অন্তর্ভুক্ত অংশ # সংজ্ঞায়িত ব্যবহার করে <time.h> এ এর

আপনি # আমদানি <সময় <<<:
    যান না। যদিও কেবলমাত্র <টাইম.ইএইচ> এর কিছু অংশ ইতিমধ্যে অন্তর্ভুক্ত ছিল, যতক্ষণ
    পর্যন্ত না # ইম্পোর্ট সম্পর্কিত, ফাইলটি ইতিমধ্যে সম্পূর্ণরূপে অন্তর্ভুক্ত রয়েছে।

শেষের সারি:

সি / সি ++ শিরোনামগুলি traditionতিহ্যগতভাবে অন্যান্য অন্তর্ভুক্ত ফাইলগুলির কিছু অংশ অন্তর্ভুক্ত করে।
সুতরাং সি / সি ++ শিরোনামগুলির জন্য, # অন্তর্ভুক্ত ব্যবহার করুন।
অবজেক্ট / অবজেক্ট ++ শিরোনামের জন্য, # ইম্পোর্ট ব্যবহার করুন।


1
দেখে মনে হচ্ছে ঝনঝন মধ্যে এই সংজ্ঞায়িত সমস্যা নেই।
ওপস

23

#includeঠিক সি এর মতোই কাজ করে #include

#importকোন শিরোনামটি ইতিমধ্যে অন্তর্ভুক্ত করা হয়েছে এবং কোনও সংকলন ইউনিটে যদি একটি শিরোনাম একাধিকবার আমদানি করা হয় তবে তা অগ্রাহ্য করা হয় track এটি হেডার গার্ড ব্যবহার করা অপ্রয়োজনীয় করে তোলে।

নীচের লাইনটি কেবলমাত্র #importউদ্দেশ্য-সিতে ব্যবহৃত হয়েছে এবং আপনার শিরোনাম যদি একবারের বেশি কিছু আমদানি করে তবে তা চিন্তা করবেন না।


2
এক মিনিটের ভান করে যে আমি সি # অন্তর্ভুক্তির সাথে পরিচিত নই (বেশিরভাগ কারণ আমি নই), # অন্তর্ভুক্তি এবং # আমদানির মধ্যে প্রধান পার্থক্য কী? এছাড়াও, আপনি কি আমাকে বলতে পারবেন হেডার গার্ডটি কী?
রায়ান গিল

@ রায়ান: সোভেনের উত্তর দেখুন।
অ্যাড্রিয়ান পেট্রেস্কু

13

আমি জানি যে এই থ্রেডটি পুরানো ... তবে "আধুনিক সময়ে" .. ঝনঝনির @importমডিউলগুলির মাধ্যমে "কৌশল অন্তর্ভুক্ত করা" এর চেয়ে অনেক বেশি উন্নত রয়েছে - এটি একেবারেই উপেক্ষা করা হয় ..

মডিউলগুলি আরও শক্তিশালী, আরও দক্ষ শব্দার্থক মডেল সহ পাঠ্য প্রিপ্রোসেসর অন্তর্ভুক্তি মডেলকে প্রতিস্থাপন করে সফ্টওয়্যার লাইব্রেরির API এ অ্যাক্সেস উন্নতি করে। ব্যবহারকারীর দৃষ্টিকোণ থেকে কোডটি কিছুটা আলাদা দেখায়, কারণ একজন # অন্তর্ভুক্ত প্রিপ্রসেসর নির্দেশের পরিবর্তে আমদানি ঘোষণা ব্যবহার করে:

@import Darwin; // Like including all of /usr/include. @see /usr/include/module.map

অথবা

@import Foundation;  //  Like #import <Foundation/Foundation.h>
@import ObjectiveC;  //  Like #import <objc/runtime.h>

যাইহোক, এই মডিউল আমদানিটি সম্পর্কিত # অন্তর্ভুক্তের থেকে বেশ আলাদাভাবে আচরণ করে: সংকলক যখন উপরের মডিউলটি আমদানি দেখে, তখন এটি মডিউলটির একটি বাইনারি উপস্থাপনা লোড করে এবং সরাসরি তার অ্যাপ্লিকেশনটিকে এপিআই উপলব্ধ করে। আমদানি ঘোষণার পূর্ববর্তী প্রিপ্রসেসর সংজ্ঞাগুলি সরবরাহ করা API তে কোনও প্রভাব ফেলবে না ... কারণ মডিউলটি নিজেই আলাদা, একক মডিউল হিসাবে সংকলিত হয়েছিল। অতিরিক্তভাবে, মডিউলটি ব্যবহার করতে প্রয়োজনীয় যে কোনও লিঙ্কার পতাকাগুলি মডিউলটি আমদানি করা হলে স্বয়ংক্রিয়ভাবে সরবরাহ করা হবে। এই শব্দার্থক আমদানি মডেল প্রিপ্রোসেসর অন্তর্ভুক্তি মডেলটির অনেকগুলি সমস্যার সমাধান করে।

মডিউলগুলি সক্ষম করতে, সংকলনের সময় - কমান্ড-লাইন ফ্ল্যাগ -fmodulesওরফে CLANG_ENABLE_MODULESইন পাস করুন Xcodeউপরে উল্লিখিত হিসাবে .. এই কৌশলটি যে কোনও এবং সমস্তকে বাধ্য করে LDFLAGS। হিসাবে, আপনি যে কোনও "OTHER_LDFLAGS" সেটিংস, পাশাপাশি কোনও "লিঙ্কিং" পর্যায়গুলি সরিয়ে নিতে পারেন ..

এখানে চিত্র বর্ণনা লিখুন

আমি অনেকগুলি স্নাপিয়ার "অনুভব" করার জন্য সংকলন / প্রবর্তনের সময়গুলি পাই (বা সম্ভবত "লিঙ্ক করার সময়" কিছুটা পিছিয়ে পড়েছি?) .. এছাড়াও, এখন বহির্মুখী প্রজেক্ট-প্রিফিক্স.পিচ ফাইলটি শুদ্ধ করার একটি দুর্দান্ত সুযোগ সরবরাহ করে, এবং বিল্ড সেটিংস সংশ্লিষ্ট, GCC_INCREASE_PRECOMPILED_HEADER_SHARING, GCC_PRECOMPILE_PREFIX_HEADER, এবং GCC_PREFIX_HEADER, ইত্যাদি

এছাড়াও, ভাল-ডকুমেন্টেড না থাকাকালীন ... আপনি module.mapনিজের ফ্রেমওয়ার্কের জন্য এস তৈরি করতে এবং এগুলিকে একই সুবিধাজনক ফ্যাশনে অন্তর্ভুক্ত করতে পারেন। আপনি কীভাবে এ জাতীয় অলৌকিক ঘটনা প্রয়োগ করতে পারেন তার কয়েকটি উদাহরণের জন্য আমার ওবজিসি-ক্ল্যাং-মডিউলগুলি গিথুব রেপোতে একবার নজর দিতে পারেন।


4

আপনি যদি সি ++ এবং ম্যাক্রোগুলির সাথে পরিচিত হন তবে

#import "Class.h" 

অনুরূপ

{
#pragma once

#include "class.h"
}

যার অর্থ আপনার অ্যাপ্লিকেশনটি চালিত হলেই কেবল আপনার ক্লাস লোড হবে।


এটি কি একবার # প্রাগমা সমর্থিত ব্যবহার? আমি সবসময় ভেবেছিলাম যে প্রগমাটি কাজ করার জন্য অন্তর্ভুক্ত এডি ফাইলের ভিতরে থাকা দরকার ।
uliwitness

@ সাক্ষী আপনি সঠিক #pragma onceঅন্তর্ভুক্ত ফাইল সঞ্চালিত না ফাইল অন্তর্ভুক্ত করা হয়। এর জন্য -1।
হার্জবিউব

1

আমার কোনও .hফাইলের ক্ষেত্রে আমার বৈশ্বিক পরিবর্তনশীল হতে পারে যা সমস্যার সৃষ্টি করছিল এবং আমি এটির externসামনে যুক্ত করে সমাধান করেছি।


0

আপনি যদি সংকলকটির চেয়ে দু'বার .h ফাইলগুলিতে একটি ফাইল অন্তর্ভুক্ত করেন তবে ত্রুটি ঘটবে। তবে আপনি যদি কোনও ফাইলকে একাধিকবার কমপোর্ট করেন তবে সংকলক এটিকে উপেক্ষা করবে।


8
#includeএকই ফাইল দু'বারের ফলে ত্রুটি হয় না
কেনেটিএম

1
সম্পূরক @ KennyTM এর মন্তব্যের, # অন্তর্ভুক্ত-ing একই ফাইল একই হেডারের মধ্যে দুবার কম্পাইল ত্রুটি ফলে না হয়, তাহলে স্বাভাবিক হেডার gards (#ifndef FILE_NAME_H # define FILE_NAME_H #end) আছে। এটি প্রত্যাশিত অনুশীলন। # ইম্পোর্ট ব্যবহার করে শিরোনাম রক্ষীদের প্রয়োজন হয় না।
jbat100

@ jbat100: #includeকেবল একটি অনুলিপি এবং পেস্ট প্রক্রিয়া। #includeপ্রহরীকে অন্তর্ভুক্ত না করে একাধিকবার ইচ্ছাকৃতভাবে ব্যবহার করা হয় , যেমন "এক্স ম্যাক্রো"।
কেনেটিএম

দুবার একটি ফাইল অন্তর্ভুক্ত করার ফলে আপনি কী অন্তর্ভুক্ত করেছেন তার উপর নির্ভর করে ত্রুটি হতে পারে। আমি সি কোড দেখেছি যা #includeএক ধরণের টেম্পলেট প্রয়োগ করে। তারা একটি করেছে #define, একটি #undefশিরোলেখকে #defineঅন্তর্ভুক্ত করেছে , ডি এবং পুনর্নির্মাণ করেছে , একই শিরোনামটি দ্বিতীয়বার অন্তর্ভুক্ত করেছিল। এর ফলে কোডটি প্যারামিটারাইজড, বৈধ এবং দ্বিগুণ অন্তর্ভুক্ত হয়েছিল, কারণ সংজ্ঞায়নের মান আলাদা ছিল। সুতরাং ব্যবহারের সুবিধাগুলি রয়েছে #includeতবে আপনি যদি C ++ বা ObjC এর মতো কোনও আধুনিক ভাষা ব্যবহার করেন তবে সাধারণত আপনার এটির প্রয়োজন হয় না।
uliwitness

0

#includeএটি অন্য ফাইল থেকে ব্যবহৃত জিনিসগুলিতে "জিনিস" পেতে পেত get #includeপ্রাক্তন:

ফাইলটিতে: main.cpp

#include "otherfile.h"

// some stuff here using otherfile.h objects,
// functions or classes declared inside

একই ফাইলটিকে আরও একবার অন্তর্ভুক্ত করা রোধ করতে প্রতিটি শিরোলেখ ফাইলের (*। এইচ) শীর্ষে শিরোনাম প্রহরী ব্যবহার করা হয় (যদি এটি ঘটে তবে আপনি সংকলনের ত্রুটি পাবেন))

ফাইলটিতে: otherfile.h

#ifndef OTHERFILE
#define OTHERFILE

// declare functions, classes or objects here

#endif

এমনকি আপনি যদি আপনার #includeকোডটিতে "otherfile.h" এন সময় রাখেন তবে এর ভিতরে এটি পুনরায় ঘোষিত হবে না।


0
#include + guard == #import

#include guardউইকি - ম্যাক্রো গার্ড, শিরোনাম রক্ষক বা ফাইল গার্ডpreprocessorএকটি বিল্ড সময়কে ধীর করতে পারে এমনদ্বারা একটি শিরোনামকে দ্বিগুণ অন্তর্ভুক্ত করতে বাধা দেয়

পরবর্তী পদক্ষেপ হয়

.pch[সম্পর্কে] =>@import [সম্পর্কে]

[# ইনপোর্ট ইন .hবা .m]

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