Увеличение C указателей - PullRequest
6 голосов
/ 23 ноября 2008

Я думал, что, если указатель c, указывающий на массив символов, будет увеличен, то он будет указывать на следующий элемент в этом массиве. Но когда я попробовал это, я обнаружил, что мне пришлось увеличить его в два раза. Попытавшись увеличить значение с помощью sizeof (char), я обнаружил, что добавление размера char было слишком большим, поэтому его пришлось разделить на два.

#include <stdio.h>

int main(int argc, char * argv[]){
   char *pi;
   int i;
   pi = argv[1];
   printf("%d args.\n",argc-1);
   printf("input: ");
   for(i=0;i<argc-1;i++){
      printf("%c, ",*pi);
      /*The line below increments pi by 1 char worth of bytes */
      //pi+=sizeof(pi)/2;
      /* An alternative to the above line is putting pi++ twice - why? */
      pi++;
      pi++;
   }
   printf("\n");
   return 0;
}

Я что-то не так делаю? или я неправильно понимаю метод приращения указателей?

Ответы [ 3 ]

20 голосов
/ 23 ноября 2008

sizeof (char) гарантированно равно 1, а sizeof (char *) - нет.

Тем не менее, ваша функция работает только случайно .

Например, попробуйте вызвать его со следующими параметрами:

abc defg

Это даст:

2 args.
input: a, c,

что совершенно неправильно. Проблема в том, что вы увеличиваете указатель на элемент 1 в argv вместо указателя на argv.

Попробуйте это:

#include <stdio.h>

int main(int argc, char * argv[]){
   char **pi;
   int i;

   pi = argv + 1;
   printf("%d args.\n",argc-1);
   printf("input: ");
   for(i=0;i<argc-1;i++){
      printf("%c, ",**pi);
      pi++;
   }
   printf("\n");
   return 0;
}

Это напечатает первый символ каждого аргумента:

2 args.
input: a, d,
4 голосов
/ 23 ноября 2008

Если у вас есть указатель ptr типа T* и вы добавляете N, то указатель будет расширен на N * sizeof (*ptr) или эквивалентный N * sizeof (T) байт. Вы просто забыли разыменовать pi. Итак, с sizeof (pi) вы получили размер char*, но не char. Ваша строка была эквивалентна pi+=sizeof(char*)/2; Указатели на вашей платформе имеют размер 4 байта. Таким образом, в действительности вы сделали pi+=2;. Напишите pi+=2, если хотите увеличить в 2 раза. Обратите внимание, что char имеет размер 1 по определению. Вам не нужно делать sizeof (char), это всегда 1.

3 голосов
/ 23 ноября 2008

sizeof (pi) возвращает размер (char *), который является типом pi (указатель, вероятно, два, четыре или восемь байтов). sizeof (char) вернет 1.

Однако еще одна вещь, которую нужно понять, это то, что всякий раз, когда вы увеличиваете указатель на число (например, pi + = sizeof (char); pi ++ и т. Д.), Вы все равно увеличиваете указатель на базовый размер. Итак:

int *ipointer = &int_array[0];
ipointer += 2;

будет фактически увеличивать ipointer в 2 раз по размеру int .

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

for (i = 1; i < argc; i++) {
    pi = argv[i];
    // ... do something with pi
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...