Восемь вопросов теста Pen Pointer помогут вам преодолеть указатель

Домашняя страница автора: paper jie's blog_CSDN blog - язык C, подробное поле алгоритма blogger

Автор этой статьи: Привет всем, я бумажный цзе, спасибо за чтение этой статьи, добро пожаловать на создание трех компаний.

Эта статья включена в колонку «Язык C», тщательно составленную для студентов колледжей и начинающих программистов. Автор тратит много денег (времени и энергии) на его создание и обладает всеми базовыми знаниями языка C. Надеюсь, это поможет читателям.

Другие столбцы: «Системный анализ языка Си», «Подробное объяснение алгоритма», «Язык Си — Грамматика».

Обмен контентом: в этом выпуске восемь тестовых вопросов помогут вам преодолеть указатель Дорогие дедушки, пожалуйста, отодвиньте скамейку и присядьте.

    -------- Не надо 998, не хочу 98, всего одна кнопка на три раза, при покупке три раза денег не потеряешь, не обманешь

предисловие

В предыдущей статье об указателях мы использовали несколько тестовых вопросов, чтобы всесторонне и многогранно объяснить взаимосвязь между указателями и массивами. В этой статье мы воспользуемся восемью классическими вопросами теста указателя, чтобы всесторонне и многогранно понять указатели.

Первый вопрос

Сколько стоит ответ? Почему этот ответ?

int main()
{
 int a[5] = { 1, 2, 3, 4, 5 };
 int *ptr = (int *)(&a + 1);
 printf( "%d,%d", *(a + 1), *(ptr - 1));
 return 0;
}

анализировать

Во-первых, мы знаем: а — это адрес первого элемента массива, а &а — весь вынутый адрес. Итак, a+1 — это адрес второго элемента, а разыменование равно 2. &a+1 — пропустить весь массив.После 5 элементов принудительный тип — int, что означает, что единицей сложения и вычитания адреса за ним является тип int. ptr — это адрес &a+1, поэтому ptr-1 должен вычесть тип int вперед, указывая на адрес 5, а разыменование равно 5.

 

второй вопрос

Предположим, что значение p равно 0x100000. Каковы значения выражений в следующей таблице?
Известно, что размер переменной структуры Test type составляет 20 байт.


struct Test
{
 int Num;
 char *pcName;
 short sDate;
 char cha[2];
 short sBa[4];
}*p;

int main()
{
 printf("%p\n", p + 0x1);
 printf("%p\n", (unsigned long)p + 0x1);
 printf("%p\n", (unsigned int*)p + 0x1);
 return 0;
}

анализировать

Через подсказку мы знаем, что это тип указателя структуры размером 20 байт и адресом 0x100000. 0x1 — это p+1, чтобы добавить тип структуры размером 20, то есть 0x100000+20=0x100014. unsigned long p — это преобразование p в целочисленный тип, добавление 1 к целочисленному типу — это добавление 1. Результат: 0x100000+1=0x100001 unsigned int* p — это преобразование p в тип указателя, поэтому p+1 — это добавить указатель размером 0x100000+ 4=0x100004

третий вопрос

Какой ответ? Почему это так?

int main()
{
 int a[4] = { 1, 2, 3, 4 };
 int *ptr1 = (int *)(&a + 1);
 int *ptr2 = (int *)((int)a + 1);
 printf( "%x,%x", ptr1[-1], *ptr2);
 return 0;
}

анализировать

a — это адрес первого элемента, &a+1 берет адрес всего массива int*(&a+1) — это преобразование типа &a+1 в тип int*, ptr[-1] может быть понимается как *(ptr- 1), ptr равен &a+1, поэтому ptr-1 должен вычесть размер типа int*, поэтому по адресу элемента 4 разыменование равно 4 int a для преобразования адреса a в целое число, а добавление 1 к целому числу означает добавление 1, мы также знаем, что адрес в памяти является байтом, добавьте здесь 1, поэтому содержимое, на которое указывает a+1, будет от 00 до 02 0x02000000

четвертый вопрос

Какой ответ? почему?

#include <stdio.h>
int main()
{
 int a[3][2] = { (0, 1), (2, 3), (4, 5) };
 int *p;
 p = a[0];
 printf( "%d", p[0]);
 return 0;
}

анализировать

Путем наблюдения: мы можем обнаружить, что в массиве есть () , поэтому это выражение с запятой, а значение справа зарезервировано, поэтому значение в () равно 1, 2 и 3 заполнено 0, за которым следует 0, поэтому массив. Средний макет выглядит так, как он выглядит после рисования.

p — это адрес a[0], а a[0] — это первая представленная строка, мы можем понимать a[0] как имя массива первой строки, поэтому a[0] — это адрес первого элемента, разыменование равно 1

пятый вопрос

Сколько стоит ответ? Почему это так?

int main()
{
 int a[5][5];
 int(*p)[4];
 p = a;
 printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
 return 0;
}

  анализировать

Массив a представляет собой двумерный массив с пятью строками и пятью столбцами, a — это адрес начального элемента, адрес a присваивается p, а q — указатель массива, а тип p — int[4].
Следовательно, каждый раз, когда добавляется p, пропускаются 4 элемента, поэтому p[4] эквивалентно *(p+4). Адрес p — это адрес после рисования картинки, а результатом вычитания двух адресов является число промежуточных элементов, поэтому &p[4][2 ]-&a[4][2]=-4
Мы знаем, что то, что хранится в компьютере, является дополнительным кодом. Если 100 напечатано
с
% P, дополнительный
код
напрямую печатается как адрес и
печатается с %d или - 4

 

Шестой вопрос

Сколько стоит ответ? Почему это так?

int main()
{
 int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
 int *ptr1 = (int *)(&aa + 1);
 int *ptr2 = (int *)(*(aa + 1));
 printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
 return 0;
}

анализировать

aa — это адрес первого элемента, который является адресом первой строки, а aa извлекает адрес всего двумерного массива
ptr1=&aa+1 &aa+1 преобразуется в тип int*, поэтому ptr-1 равен чтобы вычесть размер типа int* , в это время ptr указывает на адрес 10 элементов, разыменованных как 10

aa+1 это адрес первой строки плюс 1 на адрес второй строки, мы обнаружили, что тип aa +1 также является int*, предыдущий int* бесполезен. Его можно понимать как: int*ptr=*(aa+1), мы можем понимать *(aa+1) как aa[1], aa[1] — имя второго строкового массива, который является адресом первого элемент, и поскольку ptr==*(aa+1)==aa[1], поэтому ptr-1 указывает на элемент 5, разыменование равно 5

 

Седьмой вопрос

Сколько стоит ответ? Почему это так?

#include <stdio.h>
int main()
{
 char *a[] = {"work","at","alibaba"};
 char**pa = a;
 pa++;
 printf("%s\n", *pa);
 return 0;
}

анализировать

Нам нужно знать элемент типа char*, хранящийся в массиве a, который является адресом первого элемента работы, at и alibaba

Используйте вторичный указатель для хранения адреса a, pa==a, pa++==a++, a — адрес первого элемента, pa++==a++ — адрес второго элемента.

*pa — адрес первой буквы at, %s — напечатать эту строку символов через адрес первого символа

 

Вопрос восьмой

Сколько стоит ответ? Почему это так?

int main()
{
 char *c[] = {"ENTER","NEW","POINT","FIRST"};
 char**cp[] = {c+3,c+2,c+1,c};
 char***cpp = cp;
 printf("%s\n", **++cpp);
 printf("%s\n", *--*++cpp+3);
 printf("%s\n", *cpp[-2]+3);
 printf("%s\n", cpp[-1][-1]+1);
 return 0;
}

анализировать

Массив c хранит адрес первого элемента строки, массив cp хранит адрес адреса первого элемента, а cpp хранит адрес cp. Здесь также нужно обратить внимание на один момент: ++ и -- напрямую меняют свои значения, что повлияет на последующие расчеты.

 


Supongo que te gusta

Origin blog.csdn.net/paperjie/article/details/131350491
Recomendado
Clasificación