C-нда көрсеткіштерді көрсету ережелері қандай?

K&R doesn't go over it, but they use it. I tried seeing how it'd work by writing an example program, but it didn't go so well:

#include  
int bleh (int *); 

int main(){
    char c = '5'; 
    char *d = &c;

    bleh((int *)d); 
    return 0;  
}

int bleh(int *n){
    printf("%d bleh\n", *n); 
    return *n; 
}

Ол құрастырады, бірақ менің баспа өтінімім қоқыс айнымалыларын шығарады (олар әр бағдарлама деп атағанда). Кез келген идеялар?

52
'5' - бұл сізде int сияқты көрінеді деп ойлайсыз, бірақ бұл жай ғана 5 таңбасын білдіретін таңба ғана.
қосылды автор mah, көзі
'5' - бұл сізде int сияқты көрінеді деп ойлайсыз, бірақ бұл жай ғана 5 таңбасын білдіретін таңба ғана.
қосылды автор mah, көзі
* n мәні 4 байт болуы керек int болады. * n main() ішіндегі c жергілікті айнымалы мәнді көрсетеді. Бұл 'c' мәнін және үш байтты еске сақтап қалатындығын білдіреді. (Менің болжауымша, бұл d мәнін білдіреді.) Сіз бұл нөмірді алтыдан жазу арқылы тексере аласыз - әр екі сан әр уақытта бірдей болуы керек.
қосылды автор millimoose, көзі
* n мәні 4 байт болуы керек int болады. * n main() ішіндегі c жергілікті айнымалы мәнді көрсетеді. Бұл 'c' мәнін және үш байтты еске сақтап қалатындығын білдіреді. (Менің болжауымша, бұл d мәнін білдіреді.) Сіз бұл нөмірді алтыдан жазу арқылы тексере аласыз - әр екі сан әр уақытта бірдей болуы керек.
қосылды автор millimoose, көзі
int өлшемі үлкен емес, сондықтан '5' таңбасының кеңістігінен тыс оқиды. Кішірек деректер түрін пайдаланып, бірдей әрекетті орындап көріңіз (int c, printf «% c»)
қосылды автор SheetJS, көзі
Мен машинада (gcc, x86_64) бірдей сынақты өткіздім және компиляция қателерін таппадым, және бағдарлама әрдайым (қоқыс жоқ) жұмыс істейді. Бірақ ОС-дан басқа ештеңе жасаған жоқпын. Оғаш.
қосылды автор Andy J, көзі
Мен машинада (gcc, x86_64) бірдей сынақты өткіздім және компиляция қателерін таппадым, және бағдарлама әрдайым (қоқыс жоқ) жұмыс істейді. Бірақ ОС-дан басқа ештеңе жасаған жоқпын. Оғаш.
қосылды автор Andy J, көзі
Бұл жауапты оқыған кез келген адам R. ның төмендегі жауапты қараңыз
қосылды автор polynomial_donut, көзі

12 жауаптар

Көрсеткіштер туралы ойлағанда, бұл диаграммаларды салу көмектеседі. Көрсеткіш - бұл мәннің түрін көрсететін белгіпен еске мекен-жайды көрсететін көрсеткі. Мекенжай қайда көрінетінін көрсетеді және түрін қабылдау керек екенін білдіреді. Көрсеткі құсбелгісі көрсеткідегі көрсеткіні өзгертеді, бірақ көрсеткі көрсетілмесе.

d in main is a pointer to c which is of type char. A char is one byte of memory, so when d is dereferenced, you get the value in that one byte of memory. In the diagram below, each cell represents one byte.

-+----+----+----+----+----+----+-
 |    | c  |    |    |    |    | 
-+----+----+----+----+----+----+-
       ^~~~
       | char
       d

Сіз d -ге d түсіргенде d шын мәнінде int мәнін көрсететінін айтып отырсыз. Көптеген жүйелерде бүгінгі күні int 4 байтты алады.

-+----+----+----+----+----+----+-
 |    | c  | ?₁ | ?₂ | ?₃ |    | 
-+----+----+----+----+----+----+-
       ^~~~~~~~~~~~~~~~~~~
       | int
       (int*)d

Сіз ауысқан кезде (int *) d , сіз осы төрт байттан анықталған мәнді аласыз. Сіз алатын мән бұл ұяшықтардағы ? деп белгіленген және int қалай жадта көрсетілетініне байланысты.

Компьютер кішігірім , яғни int мәні осы жолмен есептеледі дегенді білдіреді (егер ол 4 байтты құраса): * ((int *) d) == c +? ₁ * 2⁸ +? 2 * 2¹⁶ +? ₃ * 2²⁴ . Егер сіз он алтылықпен ( printf («% x \ n», * n) ) басып шығарсаңыз, соңғы екі сан әрдайым 35 (бұл '5' таңбасының мәні болып табылады).

Кейбір басқа жүйелер өте үлкен және байтты басқа бағытта ұйымдастырады: * ((int *) d) == c * 2²⁴ +? ₁ * 2¹⁶ +? 2⁸ +? ₃ . Осы жүйелерде он алтылықтан басылған кезде мән әрқашан басталады 35 . Кейбір жүйелерде 4 байттан ерекшеленетін int мөлшері бар. Сирек бірнеше жүйе әртүрлі жолмен int ұйымдастырады, бірақ сіз оларды екіталай тапсаңыз болады.

Компилятор мен операциялық жүйеге байланысты бағдарламаны іске қосқан сайын мән әртүрлі екенін немесе әрқашан бірдей екенін, бірақ бастапқы кодқа тіпті кішкене шақтарды жасағанда өзгеретінін байқайсыз.

Кейбір жүйелерде int мәні 4 (немесе 2 немесе 8) санының мекен-жайында сақталуы керек. Бұл үйлесімділік талабы деп аталады. c мекен-жайы дұрыс тураланғанына немесе болмайтына байланысты бағдарлама бұзылуы мүмкін.

Сіздің бағдарламаңыздан айырмашылығы int мәніне ие болғанда және ол үшін көрсеткішті алған кезде не болады.

int x = 42;
int *p = &x;
-+----+----+----+----+----+----+-
 |    |         x         |    | 
-+----+----+----+----+----+----+-
       ^~~~~~~~~~~~~~~~~~~
       | int
       p

p көрсеткіші int мәнін көрсетеді. Көрсеткідегі белгі еске ұяшықтағы нәрсені дұрыс сипаттайды, сондықтан оны ажырату кезінде ешқандай тосынсыйлар жоқ.

96
қосылды
«... соңғы екі сан әрдайым 35 болады (бұл» 5 «таңбасының мәні).» Неліктен?
қосылды автор Kenneth Worden, көзі
@SummerSun Неге сіз 61626364 деп ойлайсыз? Егер сізде кішкене машина бар болса (барлық компьютерлер кішкентай болып саналса) 64636261 болады. Бұл жадтың оқылу тәртібімен ешқандай байланысы жоқ. int бәрі бір нұсқада оқылады. Бұл 4 байттың блогы int мәні ретінде қалай түсіндірілгені туралы.
қосылды автор Gilles, көзі
Жақсы сипаттама. Мен көбінесе компьютерлерде int - 32-биттік мән, бірақ басқа біріктірілген инженерлер үшін int әдетте 16-бит болып табылады және бұл қаншалықты пайдалы екенін көрсетеді және, ең алдымен, uint16_t, uint32_t, int32_t және т.с.с. пайдалану қажет. :)
қосылды автор DiBosco, көзі
Hi Gilles, кодты көргенде char * a = «abcd»; int * i = (int *) a; printf («% x \ n», * i); шығу - 64636261, бірақ бұл 61626364 болуы керек деп ойлаймын. Бұл интерфейс ішіндегі жады еске дейін оқылады ма?
қосылды автор Summer Sun, көзі
Рахмет @Gilles Деректер түрін еске сақтау тәртібіне сәйкес реттелген деп ойладым, енді кішігірімдік үшін түсінемін, бірнеше байтты қамтитын деректер түрінің мәні төменнен жоғарыға дейін жабылады.
қосылды автор Summer Sun, көзі

Көрсеткіштер туралы ойлағанда, бұл диаграммаларды салу көмектеседі. Көрсеткіш - бұл мәннің түрін көрсететін белгіпен еске мекен-жайды көрсететін көрсеткі. Мекенжай қайда көрінетінін көрсетеді және түрін қабылдау керек екенін білдіреді. Көрсеткі құсбелгісі көрсеткідегі көрсеткіні өзгертеді, бірақ көрсеткі көрсетілмесе.

d in main is a pointer to c which is of type char. A char is one byte of memory, so when d is dereferenced, you get the value in that one byte of memory. In the diagram below, each cell represents one byte.

-+----+----+----+----+----+----+-
 |    | c  |    |    |    |    | 
-+----+----+----+----+----+----+-
       ^~~~
       | char
       d

Сіз d -ге d түсіргенде d шын мәнінде int мәнін көрсететінін айтып отырсыз. Көптеген жүйелерде бүгінгі күні int 4 байтты алады.

-+----+----+----+----+----+----+-
 |    | c  | ?₁ | ?₂ | ?₃ |    | 
-+----+----+----+----+----+----+-
       ^~~~~~~~~~~~~~~~~~~
       | int
       (int*)d

Сіз ауысқан кезде (int *) d , сіз осы төрт байттан анықталған мәнді аласыз. Сіз алатын мән бұл ұяшықтардағы ? деп белгіленген және int қалай жадта көрсетілетініне байланысты.

Компьютер кішігірім , яғни int мәні осы жолмен есептеледі дегенді білдіреді (егер ол 4 байтты құраса): * ((int *) d) == c +? ₁ * 2⁸ +? 2 * 2¹⁶ +? ₃ * 2²⁴ . Егер сіз он алтылықпен ( printf («% x \ n», * n) ) басып шығарсаңыз, соңғы екі сан әрдайым 35 (бұл '5' таңбасының мәні болып табылады).

Кейбір басқа жүйелер өте үлкен және байтты басқа бағытта ұйымдастырады: * ((int *) d) == c * 2²⁴ +? ₁ * 2¹⁶ +? 2⁸ +? ₃ . Осы жүйелерде он алтылықтан басылған кезде мән әрқашан басталады 35 . Кейбір жүйелерде 4 байттан ерекшеленетін int мөлшері бар. Сирек бірнеше жүйе әртүрлі жолмен int ұйымдастырады, бірақ сіз оларды екіталай тапсаңыз болады.

Компилятор мен операциялық жүйеге байланысты бағдарламаны іске қосқан сайын мән әртүрлі екенін немесе әрқашан бірдей екенін, бірақ бастапқы кодқа тіпті кішкене шақтарды жасағанда өзгеретінін байқайсыз.

Кейбір жүйелерде int мәні 4 (немесе 2 немесе 8) санының мекен-жайында сақталуы керек. Бұл үйлесімділік талабы деп аталады. c мекен-жайы дұрыс тураланғанына немесе болмайтына байланысты бағдарлама бұзылуы мүмкін.

Сіздің бағдарламаңыздан айырмашылығы int мәніне ие болғанда және ол үшін көрсеткішті алған кезде не болады.

int x = 42;
int *p = &x;
-+----+----+----+----+----+----+-
 |    |         x         |    | 
-+----+----+----+----+----+----+-
       ^~~~~~~~~~~~~~~~~~~
       | int
       p

p көрсеткіші int мәнін көрсетеді. Көрсеткідегі белгі еске ұяшықтағы нәрсені дұрыс сипаттайды, сондықтан оны ажырату кезінде ешқандай тосынсыйлар жоқ.

96
қосылды
«... соңғы екі сан әрдайым 35 болады (бұл» 5 «таңбасының мәні).» Неліктен?
қосылды автор Kenneth Worden, көзі
@SummerSun Неге сіз 61626364 деп ойлайсыз? Егер сізде кішкене машина бар болса (барлық компьютерлер кішкентай болып саналса) 64636261 болады. Бұл жадтың оқылу тәртібімен ешқандай байланысы жоқ. int бәрі бір нұсқада оқылады. Бұл 4 байттың блогы int мәні ретінде қалай түсіндірілгені туралы.
қосылды автор Gilles, көзі
Жақсы сипаттама. Мен көбінесе компьютерлерде int - 32-биттік мән, бірақ басқа біріктірілген инженерлер үшін int әдетте 16-бит болып табылады және бұл қаншалықты пайдалы екенін көрсетеді және, ең алдымен, uint16_t, uint32_t, int32_t және т.с.с. пайдалану қажет. :)
қосылды автор DiBosco, көзі
Hi Gilles, кодты көргенде char * a = «abcd»; int * i = (int *) a; printf («% x \ n», * i); шығу - 64636261, бірақ бұл 61626364 болуы керек деп ойлаймын. Бұл интерфейс ішіндегі жады еске дейін оқылады ма?
қосылды автор Summer Sun, көзі
Рахмет @Gilles Деректер түрін еске сақтау тәртібіне сәйкес реттелген деп ойладым, енді кішігірімдік үшін түсінемін, бірнеше байтты қамтитын деректер түрінің мәні төменнен жоғарыға дейін жабылады.
қосылды автор Summer Sun, көзі
char c = '5'

0x12345678 мекенжайында char (1 байт) стекке бөлінген.

char *d = &c;

Сіз c мекен-жайын алып, оны d ішінде сақтаңыз, сондықтан d = 0x12345678 .

int *e = (int*)d;

0x12345678 дегенді int дегенге нұсқайтын компиляторды мәжбүрлеңіз, бірақ int тек бір байт ( sizeof (char)! = Sizeof (int)/code>). Сәулет немесе тіпті басқа мәндерге сәйкес ол 4 немесе 8 байт болуы мүмкін.

Сондықтан көрсеткіштің мәнін басып шығарғанда, бүтін сан бірінші байтты (яғни c ) және стекадағы басқа байттармен қабылдайды және сіздің мақсатыңыз үшін тек қоқыс болып саналады.

28
қосылды
d 0x12345678 ұстап тұру үшін жеткіліксіз
қосылды автор A Person, көзі
@Person неге бұл?
қосылды автор YoYoYonnY, көзі
Басқа дәйекті байттар қоқыс емес, бірақ d мәні, яғни 0x12345678 .
қосылды автор Kane, көзі
char c = '5'

0x12345678 мекенжайында char (1 байт) стекке бөлінген.

char *d = &c;

Сіз c мекен-жайын алып, оны d ішінде сақтаңыз, сондықтан d = 0x12345678 .

int *e = (int*)d;

0x12345678 дегенді int дегенге нұсқайтын компиляторды мәжбүрлеңіз, бірақ int тек бір байт ( sizeof (char)! = Sizeof (int)/code>). Сәулет немесе тіпті басқа мәндерге сәйкес ол 4 немесе 8 байт болуы мүмкін.

Сондықтан көрсеткіштің мәнін басып шығарғанда, бүтін сан бірінші байтты (яғни c ) және стекадағы басқа байттармен қабылдайды және сіздің мақсатыңыз үшін тек қоқыс болып саналады.

28
қосылды
d 0x12345678 ұстап тұру үшін жеткіліксіз
қосылды автор A Person, көзі
@Person неге бұл?
қосылды автор YoYoYonnY, көзі
Басқа дәйекті байттар қоқыс емес, бірақ d мәні, яғни 0x12345678 .
қосылды автор Kane, көзі

Көшіру көрсеткіштері әдетте С ішінде жарамсыз. Бірнеше себептер бар:

  1. Alignment. It's possible that, due to alignment considerations, the destination pointer type is not able to represent the value of the source pointer type. For example, if int * were inherently 4-byte aligned, casting char * to int * would lose the lower bits.

  2. Aliasing. In general it's forbidden to access an object except via an lvalue of the correct type for the object. There are some exceptions, but unless you understand them very well you don't want to do it. Note that aliasing is only a problem if you actually dereference the pointer (apply the * or -> operators to it, or pass it to a function that will dereference it).

Құпия құсбелгі көзілдіріктерінің негізгі сәттері мыналар болып табылады:

  1. Мақсатты меңзер түрі таңба түріне нұсқағанда. Таңбалар түрлеріне қатысты кез келген көрсеткішті кез келген түрге келтіруге және қажет болса, оны түпнұсқалық түрге орап сәтті түрде айналдыруға кепілдік беріледі. Сілтегішті жою ( void * ), таңбалар түріне арналған көрсеткішпен дәл сәйкес келеді, тек сіз оған ауытқу немесе оған арифметика жасауға рұқсат бермейсіз және ол автоматты түрде басқа көрсеткішке түрлеріне қажеті жоқ, демек көрсеткішті жою үшін, әдетте, осы мақсат үшін таңбалар түрлеріне қарағанда артықшылық беріледі.

  2. Мақсатты меңзер түрі құрылымның түріне сілтейтін болса, мүшелері түпнұсқадан белгіленген-құрылым құрылымының бастапқы мүшелеріне сәйкес келеді. Бұл әр түрлі объектілі-бағытталған бағдарламалау әдістері үшін пайдалы.

Кейбір қараңғы істер тілдің талаптары бойынша техникалық жағынан жақсы, бірақ проблемалық және ең жақсы болдырмайды.

12
қосылды
Сіз осы түсініксіз істермен ресми құжатқа сілтей аласыз ба?
қосылды автор Eric, көзі
@EvanBenn: Мүмкін. Егер аралық malloc арқылы алынады және сіз деректерді оны fread арқылы немесе сол сияқты сақтайсыз, онда, егер бұл өрістер дұрыс сәйкес келмесе анықтауға болады, бірақ егер олар типтің өлшемін бірнеше еселенген болса, дұрыс), ол сәйкес келетін сілтегіш түріне түрленіп, деректерді сол түрге кіргізу керек. Бірақ егер нақты код char [N] немесе қандай да бір нәрсе болса, буфермен жұмыс істесеңіз, ол жарамсыз.
қосылды автор R.., көзі
Мен кодты көріп, оны кейбір басқа көрсеткішке салатын бірнеше жерде көрдім, мысалы: int. Мысалы, камерадан RGB мәндерін немесе желіден байттарды тастаңыз. Сіздің сілтемеңіз бұл код жарамсыз дегенді білдіре ме? Кодты түзету үшін жеткілікті деректерді теңестіре ме, әлде біздің ортақ құрастырушыларымыз бұл пайдалану туралы жұмсақ болып табылады ма?
қосылды автор Evan Benn, көзі

Көшіру көрсеткіштері әдетте С ішінде жарамсыз. Бірнеше себептер бар:

  1. Alignment. It's possible that, due to alignment considerations, the destination pointer type is not able to represent the value of the source pointer type. For example, if int * were inherently 4-byte aligned, casting char * to int * would lose the lower bits.

  2. Aliasing. In general it's forbidden to access an object except via an lvalue of the correct type for the object. There are some exceptions, but unless you understand them very well you don't want to do it. Note that aliasing is only a problem if you actually dereference the pointer (apply the * or -> operators to it, or pass it to a function that will dereference it).

Құпия құсбелгі көзілдіріктерінің негізгі сәттері мыналар болып табылады:

  1. Мақсатты меңзер түрі таңба түріне нұсқағанда. Таңбалар түрлеріне қатысты кез келген көрсеткішті кез келген түрге келтіруге және қажет болса, оны түпнұсқалық түрге орап сәтті түрде айналдыруға кепілдік беріледі. Сілтегішті жою ( void * ), таңбалар түріне арналған көрсеткішпен дәл сәйкес келеді, тек сіз оған ауытқу немесе оған арифметика жасауға рұқсат бермейсіз және ол автоматты түрде басқа көрсеткішке түрлеріне қажеті жоқ, демек көрсеткішті жою үшін, әдетте, осы мақсат үшін таңбалар түрлеріне қарағанда артықшылық беріледі.

  2. Мақсатты меңзер түрі құрылымның түріне сілтейтін болса, мүшелері түпнұсқадан белгіленген-құрылым құрылымының бастапқы мүшелеріне сәйкес келеді. Бұл әр түрлі объектілі-бағытталған бағдарламалау әдістері үшін пайдалы.

Кейбір қараңғы істер тілдің талаптары бойынша техникалық жағынан жақсы, бірақ проблемалық және ең жақсы болдырмайды.

12
қосылды
Сіз осы түсініксіз істермен ресми құжатқа сілтей аласыз ба?
қосылды автор Eric, көзі
@EvanBenn: Мүмкін. Егер аралық malloc арқылы алынады және сіз деректерді оны fread арқылы немесе сол сияқты сақтайсыз, онда, егер бұл өрістер дұрыс сәйкес келмесе анықтауға болады, бірақ егер олар типтің өлшемін бірнеше еселенген болса, дұрыс), ол сәйкес келетін сілтегіш түріне түрленіп, деректерді сол түрге кіргізу керек. Бірақ егер нақты код char [N] немесе қандай да бір нәрсе болса, буфермен жұмыс істесеңіз, ол жарамсыз.
қосылды автор R.., көзі
Мен кодты көріп, оны кейбір басқа көрсеткішке салатын бірнеше жерде көрдім, мысалы: int. Мысалы, камерадан RGB мәндерін немесе желіден байттарды тастаңыз. Сіздің сілтемеңіз бұл код жарамсыз дегенді білдіре ме? Кодты түзету үшін жеткілікті деректерді теңестіре ме, әлде біздің ортақ құрастырушыларымыз бұл пайдалану туралы жұмсақ болып табылады ма?
қосылды автор Evan Benn, көзі

Мен сізге жалпы жауап қажет деп ойлаймын:

C-дегі көрсеткіштерді көрсетуде ешқандай ережелер жоқ! Тіл түсініктеме берместен басқа көрсеткішке кез келген меңзерді шығаруға мүмкіндік береді.

Бірақ бұл: Деректерді түрлендіру немесе ештеңе жасалмаған! Бұл тек қана сіз өзіңіздің жауапкершілігіңіз, бұл жүйе деректерді кейіннен дұрыс емес түсіндіре алмайды - бұл, әдетте, регламенттің бұзылуына әкеп соқтырады.

Сондықтан деректерді құйылған көрсеткіштен қолданған жағдайда, деректер үйлесімді болса, оны толығымен өзіңізге жіберіңіз!

C өнімділік үшін оңтайландырылған, сондықтан көрсеткіш/анықтамалардың жұмыс уақытының рефлексигі болмайды. Бірақ бұл баға бар - сіз бағдарламашы ретінде өзіңіз жасайтын нәрсеңізге қамқорлық жасау керек. Сіз өзіңіз туралы білуіңіз керек болса, не істеу керек болса, «заңды»

2
қосылды
Кастинг көрсеткіштері туралы ережелер бар, олардың кейбіреуі C 2011 стандартының 6.3.2.3 тармағында көрсетілген. Басқа заттардың арасында объектілерге арналған көрсеткіш басқа объектілерге объектілерге жіберілуі мүмкін және егер кері түрленсе, түпнұсқамен тең болады. Функцияларға қатысты көрсеткіштер көрсеткіштерге басқа белгілерге жіберілуі мүмкін, егер кері айналдырылса, тең болады. Көрсеткіштерді нысандарға көрсеткішке ауыстырып көрсету белгісіз әрекетке әкеледі. Нысандарға көрсеткіш белгілерге түрлендірілуі және нысанның байттарына кіру үшін пайдаланылуы мүмкін.
қосылды автор Eric Postpischil, көзі
@aqjune Сіз C стандартыны емес, кең таралған кеңейтімді сілтемесін жасайсыз. Ол тек ақпараттық сипатқа ие.
қосылды автор pipe, көзі
Көрсеткіштерді объектілерге көрсеткіштерге түрлендіруге рұқсат етіледі. «Функцияға көрсеткіш объектіге көрсеткішке жіберілуі мүмкін немесе функцияны тексеруге немесе өзгертуге мүмкіндік береді (мысалы, отладчик арқылы)», J.5.7
қосылды автор aqjune, көзі

Мен сізге жалпы жауап қажет деп ойлаймын:

C-дегі көрсеткіштерді көрсетуде ешқандай ережелер жоқ! Тіл түсініктеме берместен басқа көрсеткішке кез келген меңзерді шығаруға мүмкіндік береді.

Бірақ бұл: Деректерді түрлендіру немесе ештеңе жасалмаған! Бұл тек қана сіз өзіңіздің жауапкершілігіңіз, бұл жүйе деректерді кейіннен дұрыс емес түсіндіре алмайды - бұл, әдетте, регламенттің бұзылуына әкеп соқтырады.

Сондықтан деректерді құйылған көрсеткіштен қолданған жағдайда, деректер үйлесімді болса, оны толығымен өзіңізге жіберіңіз!

C өнімділік үшін оңтайландырылған, сондықтан көрсеткіш/анықтамалардың жұмыс уақытының рефлексигі болмайды. Бірақ бұл баға бар - сіз бағдарламашы ретінде өзіңіз жасайтын нәрсеңізге қамқорлық жасау керек. Сіз өзіңіз туралы білуіңіз керек болса, не істеу керек болса, «заңды»

2
қосылды
Кастинг көрсеткіштері туралы ережелер бар, олардың кейбіреуі C 2011 стандартының 6.3.2.3 тармағында көрсетілген. Басқа заттардың арасында объектілерге арналған көрсеткіш басқа объектілерге объектілерге жіберілуі мүмкін және егер кері түрленсе, түпнұсқамен тең болады. Функцияларға қатысты көрсеткіштер көрсеткіштерге басқа белгілерге жіберілуі мүмкін, егер кері айналдырылса, тең болады. Көрсеткіштерді нысандарға көрсеткішке ауыстырып көрсету белгісіз әрекетке әкеледі. Нысандарға көрсеткіш белгілерге түрлендірілуі және нысанның байттарына кіру үшін пайдаланылуы мүмкін.
қосылды автор Eric Postpischil, көзі
@aqjune Сіз C стандартыны емес, кең таралған кеңейтімді сілтемесін жасайсыз. Ол тек ақпараттық сипатқа ие.
қосылды автор pipe, көзі
Көрсеткіштерді объектілерге көрсеткіштерге түрлендіруге рұқсат етіледі. «Функцияға көрсеткіш объектіге көрсеткішке жіберілуі мүмкін немесе функцияны тексеруге немесе өзгертуге мүмкіндік береді (мысалы, отладчик арқылы)», J.5.7
қосылды автор aqjune, көзі

char сілтегішінің бар. Сонымен, сіздің жүйеңіз білетіндіктен, жады мекенжайында sizeof (char) кеңістігінде char мәні бар. Сіз оны int * -ке шығарғанда, сіз sizeof (int) деректерімен жұмыс істейсіз, сондықтан сіз өзіңіздің және кейбір жадты қоқыстарды тұтас бүтін ретінде басып шығарасыз .

2
қосылды

char сілтегішінің бар. Сонымен, сіздің жүйеңіз білетіндіктен, жады мекенжайында sizeof (char) кеңістігінде char мәні бар. Сіз оны int * -ке шығарғанда, сіз sizeof (int) деректерімен жұмыс істейсіз, сондықтан сіз өзіңіздің және кейбір жадты қоқыстарды тұтас бүтін ретінде басып шығарасыз .

2
қосылды

Қоқыс құндылығы іс жүзінде сіз bleh() функциясын деп жарияламай тұрып шақырдыңыз.

In case of C++ you will get compilation error but in c, the compiler assumes that the return type of the function is int, whereas, your function is returning a pointer to integer.

See this for more info : http://www.geeksforgeeks.org/g-fact-95/

2
қосылды
Функция шақыру алдында жарияланады.
қосылды автор ad3angel1s, көзі

Қоқыс құндылығы іс жүзінде сіз bleh() функциясын деп жарияламай тұрып шақырдыңыз.

In case of C++ you will get compilation error but in c, the compiler assumes that the return type of the function is int, whereas, your function is returning a pointer to integer.

See this for more info : http://www.geeksforgeeks.org/g-fact-95/

2
қосылды
Функция шақыру алдында жарияланады.
қосылды автор ad3angel1s, көзі