الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

عكس سلسلتين نصيتين

بدأه mhewedy في 22 يونيو 2010 · 6 رد · 485 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

تفضولو كود يقوم بعكس سلسلتين نصيتين بإستخدام pointer arithmetic :

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

void reverse(char* str, char** ret);

int main(void)
{
	char* str = "helloWorld";
	char* ret =  (char*)(malloc(sizeof(char*)));
	char** ptr = &ret;

	reverse(str, ptr);

	printf("%s", *ptr);

	return 0;
}

void reverse(char* str, char** ptr)
{
	**ptr = '\0';		// to terminate char string
	(*ptr)--;
	while (*str != '\0'){
		**ptr = *str;
		str++; (*ptr)--;
	}
	(*ptr)++;
}

كل الشكر و التقدير و العرفان للأخ GammingMaster :D

#2

انت ممكن تخلى المعامل الثانى مؤشر لحرف (مثل نوع المعامل الأول) و من ثمَّ تقوم بإجراء العمليات عليه كما تريد و بعدها تعيده كقيمه معاده من الداله و القيمه المعاده تستقبلها مره اخرى داخل المتغير الموجود بالداله main.

ثانيا يوجد خطأ لديك فى هذا السطر:

char* ret =  (char*)(malloc(sizeof(char*)));

النوع char* فى الأنظمة 32bit مساحته 4 بايت و فى الأنظمه 64bit مساحته 8 بايت و بالتالى المساحه المحجوزه داخل المتغير ret ستكون دائما و ابدا اما 4 او 8.

مدونتي: C++ Tips and Tricks

#3

شكرا جزيلا لردك:

اقتباس

انت ممكن تخلى المعامل الثانى مؤشر لحرف (مثل نوع المعامل الأول) و من ثمَّ تقوم بإجراء العمليات عليه كما تريد و بعدها تعيده كقيمه معاده من الداله و القيمه المعاده تستقبلها مره اخرى داخل المتغير الموجود بالداله main

كنت أريد أن أتعلم موضوع ال

char**

:D

اقتباس

النوع char* فى الأنظمة 32bit مساحته 4 بايت و فى الأنظمه 64bit مساحته 8 بايت و بالتالى المساحه المحجوزه داخل المتغير ret ستكون دائما و ابدا اما 4 او 8.

أليس ال char* واحد بايت؟ و ما الحل إذن؟

جزاك الله خيرا

تم تعديل هذه المشاركة بواسطة هويدي في 22 يونيو 2010 في 23:05

#4
اقتباس
أليس ال char* واحد بايت؟ و ما الحل إذن؟

الـ char هو واحد بايت اما char* هو مؤشر لبايت و حجمه 4 بايت، قم بتعديل سطر الكود ليكون كالتالى:

char* ret =  (char*)malloc(strlen(str) + 1);

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#5

مم, واضح أن أحجام جميع الموشرات هي 4 (على الماكينة التي أعمل عليها ):

فكل هذا يعطي 4

   printf("%i\n", sizeof(void*));
	printf("%i\n", sizeof(char*));
	printf("%i\n", sizeof(int*));
	printf("%i\n", sizeof(long*));
	printf("%i\n", sizeof(short*));
	printf("%i\n", sizeof(long long*));
	printf("%i\n", sizeof(unsigned*));
	printf("%i\n", sizeof(unsigned short*));
	printf("%i\n", sizeof(unsigned long*));
	printf("%i\n", sizeof(unsigned long long*));

إذن لم يشترط تعريف المؤشر من نفس نوع المتغير, و لم يتم عمل cast للتحويل من مؤشر float (مثلا) لمؤشر int ؟

أنا عارف إني مزهقك في عيشتك, بس معلش إستحملني :D

تم تعديل هذه المشاركة بواسطة هويدي في 22 يونيو 2010 في 23:46

#6

حجم أي مؤشر يعتمد على الـArchitecture الذي سيتم ترجمة الكود ليعمل عليه ، فمثلا اذا كان الكود سيعمل على انظمة x86 فسيكون حجم المؤشر 32 بت = 4 بايت ، اما ان كان سيعمل على انظمة x86-64 فسيطون حجمه 64 بت = 8 بايت .

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#7
اقتباس
لم يتم عمل cast للتحويل من مؤشر float (مثلا) لمؤشر int

يحذر الpointer cast من الانواع المختلفة لبعضها الا من الvoid* للانواع الاقل او العكس (غير متاكد من كلمة "العكس") .

التحويل بين الانواع المختلفة قد يودى الى crash او انخفاض حاد فى الاداء . (لاسباب خاصة بalign الموشرات فى الذاكرة والخ )

اقتباس
إذن لم يشترط تعريف المؤشر من نفس نوع المتغير ؟

وعندما تعمل dereference للمتغير , كيف سيتعامل مع محتواة . عموما هناك void* ليكون عامل وتمررة بcast عند الاستخدام

اقتباس
char**

هو pointer to pointer اى موشر يوشر على اخر لذلك تعطية عنوان الموشر الاخر الذى تريد الاشارة الية .

مثلا

int x = 5 ;
        int *px = &x;
        int** dpx = &px;
        printf(" all will print value \n%d %d %d",x,*px,**dpx);
        printf("\nall will print address of value \n%p %p \n1",px,*dpx);

        return 0;

مارايك بهذا

char****************************************************

تقريبا الذاكرة كلها موشرات بتشاور على بعض :lol:

اقتباس
حجم أي مؤشر يعتمد على الـArchitecture الذي سيتم ترجمة الكود ليعمل عليه ، فمثلا اذا كان الكود سيعمل على انظمة x86 فسيكون حجم المؤشر 32 بت = 4 بايت ، اما ان كان سيعمل على انظمة x86-64 فسيطون حجمه 64 بت = 8 بايت

اذا كنت تتسائل لماذا , فهو بسبب ان الموشر حجمة يجب ان يتحمل range عناوين اكبر .

مثلا 32 بت يكفون ان يتحملوا الاشارة الى 2^32 بايت (اقل وحدة يمكن الاشارة اليها)= تقريبا 4096 = 4 جيجا وهذا هى الذاكرة التى تستطيع قراتها المعالجات ال 32 بت (وغالبا الaddress bus يكون 32 بت لتكافوء السرعة )

اما ال64 بت يمكنة تحمل 2^64 تقريبا 16 exa

تم تعديل هذه المشاركة بواسطة apex في 23 يونيو 2010 في 07:45

name : mohamedyosry

مواضيع مشابهة