Показывая размер массива с помощью указателей в c ++, просим пояснить, почему мы используем *, как показано в коде ниже [duplicate]

Начиная с Python 2.6 существует альтернатива: метод str.format () . Ниже приведены некоторые примеры использования существующего оператора строкового формата (% ):

  & gt; gt; & gt;  "Имя:% s, возраст:% d"% ('John', 35) 'Имя: John, age: 35' & gt; & gt; & gt; & gt; & gt; & gt;  i = 45 & gt; & gt;  'dec:% d / oct:% # o / hex:% # X'% (i, i, i) 'dec: 45 / oct: 055 / hex: 0X2D' & gt; & gt; & gt; & gt;  "MM / DD / YY =% 02d /% 02d /% 02d"% (12, 7, 41) 'MM / DD / YY = 12/07/41' & gt; & gt; & gt; & gt;  «Итого с налогом: $%. 2f '% (13.00 * 1.0825)« Всего с налогом: $ 14,07 & gt; & gt; & gt; & gt;  d = {'web': 'user', 'page': 42} & gt; & gt; & gt; & gt; & gt;  'http: //xxx.yyy.zzz/% (web) s /% (страница) d.html'% d 'http: //xxx.yyy.zzz/user/42.html'  

Ниже приведены эквивалентные фрагменты, но с использованием str.format () :

  & gt; gt; gt;  «Имя: {0}, возраст: {1}". Format ('John', 35) 'Name: John, age: 35' & gt; & gt; & gt; & gt; & gt;  i = 45 & gt; & gt;  'dec: {0} / oct: {0: #o} / hex: {0: #X}'. format (i) 'dec: 45 / oct: 0o55 / hex: 0X2D' & gt; gt;  "MM / DD / YY = {0: 02d} / {1: 02d} / {2: 02d}". Format (12, 7, 41) 'MM / DD / YY = 12/07/41' & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt;  ; & GT;  «Итого с налогом: $ {0: .2f}». Формат (13.00 * 1.0825) «Всего с налогом: $ 14.07» & gt; & gt; & gt; & gt;  d = {'web': 'user', 'page': 42} & gt; & gt; & gt; & gt; & gt;  'http: //xxx.yyy.zzz/ {web} / {page} .html'.format (** d)' http: //xxx.yyy.zzz/user/42.html ' [  ! d12] 

Как и Python 2.6+, все выпуски Python 3 (до сих пор) понимают, как это сделать. Я бесстыдно разорвал этот материал прямо из моей хардкорной интро-книги Python и слайдов для курсов Intro + Intermediate Python, которые я предлагаю время от времени. [D7]: -

)

726
задан Peter Mortensen 28 February 2013 в 16:16
поделиться

16 ответов

Исполнительное резюме:

int a[17];
size_t n = sizeof(a)/sizeof(a[0]);

Чтобы определить размер вашего массива в байтах, вы можете использовать оператор sizeof:

int a[17];
size_t n = sizeof(a);

На моем компьютере, ints имеют длину 4 байта, поэтому n равно 68.

Чтобы определить количество элементов в массиве, мы можем разделить общий размер массива на размер элемента массива. Вы можете сделать это с типом, например:

int a[17];
size_t n = sizeof(a) / sizeof(int);

и получить правильный ответ (68/4 = 17), но если тип a изменился, у вас будет неприятная ошибка, если вы также забыли изменить sizeof(int).

Таким образом, предпочтительным делителем является sizeof(a[0]), размер элемента zeroeth массива.

int a[17];
size_t n = sizeof(a) / sizeof(a[0]);

Еще одно преимущество что теперь вы можете легко параметризовать имя массива в макросе и получить:

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int a[17];
size_t n = NELEMS(a);
918
ответ дан Jens 16 August 2018 в 14:13
поделиться
  • 1
    Сгенерированный код будет идентичным, поскольку компилятор знает тип * int_arr во время компиляции (и, следовательно, значение sizeof (* int_arr)). Он будет постоянным, и компилятор может соответствующим образом оптимизировать. – Mark Harrison 21 September 2013 в 20:58
  • 2
    Это должно иметь место со всеми компиляторами, поскольку результаты sizeof определяются как константа времени компиляции. – Mark Harrison 22 September 2013 в 06:39
  • 3
    Важно : Не прекращайте читать здесь, прочитайте следующий ответ! Это работает только для массивов в стеке , например. если вы используете malloc () или получаете доступ к параметру функции, вам не повезло. Смотри ниже. – Markus 27 January 2014 в 16:21
  • 4
    Для программирования API Windows на C или C ++ существует ARRAYSIZE макрос, определенный в WinNT.h (который затягивается другими заголовками). Поэтому пользователям WinAPI не нужно определять свой собственный макро. – Lumi 23 April 2014 в 09:24
  • 5
    @Markus работает для любой переменной, которая имеет тип массива; это не должно быть «в стеке». Например. static int a[20];. Но ваш комментарий полезен читателям, которые могут не понимать разницу между массивом и указателем. – M.M 6 October 2014 в 03:45

Для многомерных массивов это немного сложнее. Часто люди определяют явные макроконстанты, т. Е.

#define g_rgDialogRows   2
#define g_rgDialogCols   7

static char const* g_rgDialog[g_rgDialogRows][g_rgDialogCols] =
{
    { " ",  " ",    " ",    " 494", " 210", " Generic Sample Dialog", " " },
    { " 1", " 330", " 174", " 88",  " ",    " OK",        " " },
};

. Но эти константы могут быть вычислены и во время компиляции с помощью sizeof :

#define rows_of_array(name)       \
    (sizeof(name   ) / sizeof(name[0][0]) / columns_of_array(name))
#define columns_of_array(name)    \
    (sizeof(name[0]) / sizeof(name[0][0]))

static char* g_rgDialog[][7] = { /* ... */ };

assert(   rows_of_array(g_rgDialog) == 2);
assert(columns_of_array(g_rgDialog) == 7);

Примечание что этот код работает на C и C ++. Для массивов с более чем двумя измерениями используйте

sizeof(name[0][0][0])
sizeof(name[0][0][0][0])

и т. Д., Ad infinitum.

13
ответ дан Andreas Spindler 16 August 2018 в 14:13
поделиться
#define SIZE_OF_ARRAY(_array) (sizeof(_array) / sizeof(_array[0]))
9
ответ дан Andy Nugent 16 August 2018 в 14:13
поделиться
  • 1
    Обратите внимание, что это работает только для реальных массивов, а не для указателей, которые указывают на массивы. – David Schwartz 7 January 2017 в 21:18
int size = (&arr)[1] - arr;

Проверьте эту ссылку для объяснения

32
ответ дан Arjun Sreedharan 16 August 2018 в 14:13
поделиться
  • 1
    Малый nitpick: результат вычитания указателя имеет тип ptrdiff_t. (Обычно в 64-битной системе это будет больший тип, чем int). Даже если вы измените int на ptrdiff_t в этом коде, у него все еще есть ошибка, если arr занимает более половины адресного пространства. – M.M 6 October 2014 в 03:37
  • 2
    @ M.M Еще одна небольшая нитьтика: в зависимости от вашей архитектуры системы адресное пространство почти не превышает размер указателя на большинстве систем. Например, Windows ограничивает адресное пространство для 64-битных приложений до 8 ТБ или 44 бит. Поэтому даже если у вас есть массив размером более половины вашего адресного пространства 4.1TB, это не будет ошибкой. Только если ваше адресное пространство превышает 63 бит в этих системах, возможно даже столкнуться с такой ошибкой. В общем, не беспокойтесь об этом. – Aidiakapi 8 January 2016 в 18:00
  • 3
    @Aidiakapi на 32-разрядной x86 Linux или в Windows с опцией /3G у вас есть разделение пользователя / ядра 3G / 1G, что позволяет иметь размер массивов до 75% от размера адресного пространства. – Ruslan 10 January 2018 в 13:26
  • 4
    Рассмотрим foo buf1[80]; foo buf2[sizeof buf1/sizeof buf1[0]]; foo buf3[(&buf1)[1] - buf1]; как глобальные переменные. Объявление buf3[] не работает, поскольку (&buf1)[1] - buf1 не является константой. – chux 21 May 2018 в 16:01

Если вы действительно хотите сделать это, чтобы передать свой массив, я предлагаю реализовать структуру для хранения указателя на тип, который вам нужен, массив и целое число, представляющее размер массива. Затем вы можете передать это своим функциям. Просто присвойте значение переменной массива (указатель на первый элемент) этому указателю. Затем вы можете пойти Array.arr[i], чтобы получить i-й элемент, и использовать Array.size, чтобы получить количество элементов в массиве.

Я включил для вас некоторый код. Это не очень полезно, но вы можете расширить его с большим количеством функций. Если честно, если это то, что вам нужно, вы должны прекратить использовать C и использовать другой язык с этими встроенными функциями.

/* Absolutely no one should use this...
   By the time you're done implementing it you'll wish you just passed around
   an array and size to your functions */
/* This is a static implementation. You can get a dynamic implementation and 
   cut out the array in main by using the stdlib memory allocation methods,
   but it will work much slower since it will store your array on the heap */

#include <stdio.h>
#include <string.h>
/*
#include "MyTypeArray.h"
*/
/* MyTypeArray.h 
#ifndef MYTYPE_ARRAY
#define MYTYPE_ARRAY
*/
typedef struct MyType
{
   int age;
   char name[20];
} MyType;
typedef struct MyTypeArray
{
   int size;
   MyType *arr;
} MyTypeArray;

MyType new_MyType(int age, char *name);
MyTypeArray newMyTypeArray(int size, MyType *first);
/*
#endif
End MyTypeArray.h */

/* MyTypeArray.c */
MyType new_MyType(int age, char *name)
{
   MyType d;
   d.age = age;
   strcpy(d.name, name);
   return d;
}

MyTypeArray new_MyTypeArray(int size, MyType *first)
{
   MyTypeArray d;
   d.size = size;
   d.arr = first;
   return d;
}
/* End MyTypeArray.c */


void print_MyType_names(MyTypeArray d)
{
   int i;
   for (i = 0; i < d.size; i++)
   {
      printf("Name: %s, Age: %d\n", d.arr[i].name, d.arr[i].age);
   }
}

int main()
{
   /* First create an array on the stack to store our elements in.
      Note we could create an empty array with a size instead and
      set the elements later. */
   MyType arr[] = {new_MyType(10, "Sam"), new_MyType(3, "Baxter")};
   /* Now create a "MyTypeArray" which will use the array we just
      created internally. Really it will just store the value of the pointer
      "arr". Here we are manually setting the size. You can use the sizeof
      trick here instead if you're sure it will work with your compiler. */
   MyTypeArray array = new_MyTypeArray(2, arr);
   /* MyTypeArray array = new_MyTypeArray(sizeof(arr)/sizeof(arr[0]), arr); */
   print_MyType_names(array);
   return 0;
}
3
ответ дан bartimar 16 August 2018 в 14:13
поделиться
  • 1
    Не удается перекодировать код, который делает strcpy(d.name, name); без обработки переполнения. – chux 20 May 2016 в 20:58

Способ sizeof - это правильный путь iff , который вы имеете в виду массивы, не полученные в качестве параметров. Массив, отправленный как параметр функции, рассматривается как указатель, поэтому sizeof вернет размер указателя вместо массива.

Таким образом, внутри функций этот метод не работает. Вместо этого всегда передавайте дополнительный параметр size_t size, указывающий количество элементов в массиве.

Тест:

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

void printSizeOf(int intArray[]);
void printLength(int intArray[]);

int main(int argc, char* argv[])
{
    int array[] = { 0, 1, 2, 3, 4, 5, 6 };

    printf("sizeof of array: %d\n", (int) sizeof(array));
    printSizeOf(array);

    printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
    printLength(array);
}

void printSizeOf(int intArray[])
{
    printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}

void printLength(int intArray[])
{
    printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}

Выход (в 64-разрядной ОС Linux):

sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2

Вывод (в 32-разрядной ОС Windows):

sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1
618
ответ дан Elideb 16 August 2018 в 14:13
поделиться
  • 1
    почему length of parameter:2, если передан только указатель на первый элемент массива? – Bbvarghe 5 August 2013 в 03:42
  • 2
    @Bbvarghe Это потому, что указатели в 64-битных системах - 8 байтов (sizeof (intArray)), но ints все еще (обычно) длиной 4 байта (sizeof (intArray [0])). – Elideb 28 August 2013 в 18:33
  • 3
    @Pacerier: нет правильного кода - обычным решением является передача длины вместе с массивом в качестве отдельного аргумента. – Jean Hominal 5 October 2013 в 14:58
  • 4
    Подождите, так что нет способа получить доступ к массиву непосредственно из указателя и увидеть его размер? Новинка здесь. – sudo 1 December 2013 в 08:37
  • 5
    @Elideb Спасибо за это. Я думаю, что я прочитал что-то подобное в другом месте после того, как я разместил комментарий. Что в конечном итоге помогло мне понять, что когда sizeof вызывается в том же объеме, что и объявлен массив, он видит его параметр как параметр типа int [7] (используя пример в ответе), но при вызове в другой области он видит свой параметр как параметр типа int *. В основном то же самое, что вы сказали, только по моим собственным словам :) – Nickolai 24 February 2015 в 17:09

Вы можете использовать оператор sizeof, но он не будет работать для функций, потому что для ссылки на указатель вы можете сделать следующее, чтобы найти длину массива:

len = sizeof(arr)/sizeof(arr[0])

Код, первоначально найденный здесь : C программа для поиска числа элементов в массиве

20
ответ дан Joncom 16 August 2018 в 14:13
поделиться

Вы можете использовать оператор &. Вот исходный код:

#include<stdio.h>
#include<stdlib.h>
int main(){

    int a[10];

    int *p; 

    printf("%p\n", (void *)a); 
    printf("%p\n", (void *)(&a+1));
    printf("---- diff----\n");
    printf("%zu\n", sizeof(a[0]));
    printf("The size of array a is %zu\n", ((char *)(&a+1)-(char *)a)/(sizeof(a[0])));


    return 0;
};

Вот пример вывода

1549216672
1549216712
---- diff----
4
The size of array a is 10
1
ответ дан M.M 16 August 2018 в 14:13
поделиться
  • 1
    Я не спускал вниз, но это как удар ноготь с кирпичом, потому что вы не заметили, что рядом с вами молоток. Кроме того, люди склонны хмуриться от использования неинициализированных переменных ... но здесь я предполагаю, что он служит вашей цели достаточно хорошо. – Dmitri 11 September 2014 в 22:18
  • 2
    @Dmitri не доступны никакие неинициализированные переменные здесь – M.M 6 October 2014 в 03:39
  • 3
    Хммм. Вычитание указателя приводит к ptrdiff_t. sizeof() приводит к size_t. C does not определяет более широкий или более высокий / тот же ранг. Таким образом, тип частного ((char *)(&a+1)-(char *)a)/(sizeof(a[0])) не обязательно size_t, и, таким образом, печать с z может привести к UB. Просто использовать printf("The size of array a is %zu\n", sizeof a/sizeof a[0]); достаточно. – chux 20 May 2016 в 21:10
  • 4
    (char *)(&a+1)-(char *)a не является константой и может быть рассчитан во время выполнения, даже с фиксированным размером a[10]. sizeof(a)/sizeof(a[0]) постоянно выполняется во время компиляции в этом случае. – chux 21 May 2018 в 16:17

Стоит отметить, что sizeof не помогает при работе со значением массива, которое распалось на указатель: хотя он указывает на начало массива, компилятору он совпадает с указателем на один элемент этого массива. Указатель не «помнит» ничего о массиве, который использовался для его инициализации.

int a[10];
int* p = a;

assert(sizeof(a) / sizeof(a[0]) == 10);
assert(sizeof(p) == sizeof(int*));
assert(sizeof(*p) == sizeof(int));
104
ответ дан Magnus Hoff 16 August 2018 в 14:13
поделиться
  • 1
    Я помню, что CRAY имел C с char из 32 бит. Весь стандарт говорит о том, что целочисленные значения от 0 до 127 могут быть представлены, а его диапазон составляет как минимум от -127 до 127 (char подписан) или от 0 до 255 (char беззнаковый). – vonbrand 1 February 2013 в 22:57
  • 2
    Это отличный ответ. Я хочу прокомментировать, что все вышеприведенные утверждения оцениваются как TRUE. – Javad 4 June 2015 в 23:23

Лучший способ сохранить эту информацию, например, в структуре:

typedef struct {
     int *array;
     int elements;
} list_s;

Реализовать все необходимые функции, такие как создание, уничтожение, проверка равенства и все остальное, что вам нужно. Это легче передать в качестве параметра.

3
ответ дан Paulo Pinheiro 16 August 2018 в 14:13
поделиться
  • 1
    Любая причина для int elements против size_t elements? – chux 20 May 2016 в 21:00

Использование:

int a=[10] = {1, 2, 3, 4, 5};
int n = sizeof(a);
printf("%d", n);

Выход:

5

Причина: вычисляет количество элементов, хранящихся в массиве, а не количество свободных пространств, выделенных ему.

18
ответ дан Peter Mortensen 16 August 2018 в 14:13
поделиться
  • 1
    ... да, и мы обеспечиваем assert(sizeof(char) < sizeof(int)). Это глубокая концепция ... – Andreas Spindler 26 January 2012 в 11:02
  • 2
    Я читал, что правильный способ объявления целочисленных констант в C состоит в использовании объявления enum. – Raffi Khatchadourian 4 August 2013 в 00:08
  • 3
    Вопрос не в C ++ ..... – Pacerier 21 September 2013 в 07:56
  • 4
    Спасибо за объяснение. Исходная версия приводит к ошибке времени компиляции. Отчеты Clang & quot; индексированное значение не вл етс массивом, указателем или вектором ". Это кажется предпочтительным поведением в этом случае, хотя ваши комментарии относительно порядка оценки в макросах хорошо приняты. – Mark Harrison 28 February 2014 в 04:30
  • 5
    Я не думал о жалобе компилятора как автоматическое уведомление о некорректном типе. Спасибо! – user 28 February 2014 в 04:46
  • 6
    int noofele = sizeof(arr)/sizeof(int); только на полпути лучше, чем кодирование int noofele = 9;. Использование sizeof(arr) поддерживает гибкость при изменении размера массива. Тем не менее sizeof(int) нуждается в обновлении, если тип arr[] изменится. Лучше использовать sizeof(arr)/sizeof(arr[0]), даже если тип хорошо известен. Непонятно, почему использование int для noofele против size_t, тип, возвращаемый sizeof(). – chux 20 May 2016 в 20:50
  • 7
    Любопытно, что код использовал size_t size_of_element еще int с int n = sizeof (a) / sizeof (a[0]); , а не size_t n = sizeof (a) / sizeof (a[0]); – chux 20 May 2016 в 21:02
  • 8
    Это даже компилируется? Что int a=[10] должен делать? – Peter Mortensen 9 March 2017 в 05:32
  • 9
    Вот почему я люблю stackoverflow, моя жена иногда смотрит на меня неловко, когда я смеюсь, глядя на код. – Seraf 11 March 2017 в 20:33
  • 10
  • 11
    Есть ли причина не использовать (sizeof (x) / sizeof (*x))? – seriousdev 28 March 2017 в 13:40
  • 12
    Привет @Yogeesh H T, можете ли вы ответить на вопрос о сомнении. Мне также очень интересно узнать, как int n = sizeof (a) / sizeof (a [0]) задает длину массива и почему мы не используем size_t для длины массива. Может ли кто-нибудь ответить на него? – Brain 21 July 2017 в 19:55
  • 13
    @Brain sizeof (a) дает sizeof всех элементов, присутствующих в массиве sizeof (a [0]) дает размер 1-го элемента. Предположим, что a = {1,2,3,4,5}; sizeof (a) = 20 байт (если sizeof (int) = 4 байта умножить 5), sizeof (a [0]) = 4 байта, поэтому 20/4 = 5 нет элементов – Yogeesh H T 24 July 2017 в 11:28
  • 14
    Концепция в порядке, но синтаксис необходимо исправить – Wei Yuang Hsu 3 November 2017 в 08:50
  • 15
    @YogeeshHT Для очень больших массивов, таких как char a[INT_MAX + 1u];, int n, как используется в int n = sizeof (a) / sizeof (a[0]);, недостаточно (это UB). Использование size_t n = sizeof (a) / sizeof (a[0]); не несет этой проблемы. – chux 21 May 2018 в 16:10
0
ответ дан Pygirl 16 August 2018 в 14:13
поделиться
sizeof(array) / sizeof(array[0])
10
ответ дан Ted Percival 16 August 2018 в 14:13
поделиться

@ Магнус: Стандарт определяет sizeof как уступающий количеству байтов в объекте, а sizeof (char) всегда один.

Edit: ANSI C ++ standard section 5.3.3 Sizeof:

Оператор sizeof дает количество байтов в объекте представление его операнда. [...] sizeof (char), sizeof (signed char) и sizeof (unsigned char) равны 1; результат sizeof, примененный к любому другому фундаментальному типу, определяется реализацией.

Раздел 1.6 Модель памяти C ++:

Фундаментальная единица хранения в C ++ модель памяти - это байт. Байт, по крайней мере, достаточно большой, чтобы содержать любой элемент базового набора символов выполнения и состоит из непрерывной последовательности бит, число которой определяется реализацией.

4
ответ дан Tim Cooper 16 August 2018 в 14:13
поделиться

Размерный «трюк» - это лучший способ, который я знаю, с одним маленьким, но (для меня это серьезный питомец) важное изменение в использовании круглых скобок.

Поскольку запись в Википедии делает clear, C sizeof не является функцией; это оператор. Таким образом, он не требует скобок вокруг своего аргумента, если аргумент не является именем типа. Это легко запомнить, так как он делает аргумент похожим на выражение cast, которое также использует скобки.

So: Если у вас есть следующее:

int myArray[10];

Вы можете найти количество элементов с таким кодом:

size_t n = sizeof myArray / sizeof *myArray;

Это, для меня, намного легче, чем альтернатива с круглыми скобками. Я также предпочитаю использовать звездочку в правой части деления, поскольку она более кратка, чем индексация.

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

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

Например, скажем, у вас есть функция, которая выводит некоторые данные в виде потока байтов, например, по сети. Назовем функцию send() и сделаем в качестве аргументов указатель на отправляемый объект и количество байтов в объекте. Итак, прототип становится:

void send(const void *object, size_t size);

И тогда вам нужно отправить целое число, поэтому вы его кодируете следующим образом:

int foo = 4711;
send(&foo, sizeof (int));

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

send(&foo, sizeof foo);

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

36
ответ дан unwind 16 August 2018 в 14:13
поделиться
  • 1
    Btw, являются ли они одинаковыми инструкциями на уровне процессора? Требуется ли sizeof(int) меньше инструкций, чем sizeof(foo)? – Pacerier 21 September 2013 в 07:53
  • 2
    @Pacerier: нет, они идентичны. Подумайте о int x = 1+1; по сравнению с int x = (1+1);. Здесь круглые скобки чисто абсолютно эстетичны. – quetzalcoatl 5 October 2013 в 14:22
  • 3
    @Aidiakapi Это неправда, рассмотрите VLA C99. – unwind 13 January 2016 в 14:18
  • 4
    @unwind Спасибо, я стою исправлено. Чтобы исправить мой комментарий, sizeof всегда будет постоянным в C ++ и C89. С массивами переменной длины C99 он может быть оценен во время выполнения. – Aidiakapi 13 January 2016 в 17:47

@Skizz: Я уверен, что я прав, хотя лучший «источник», который я могу вам дать в данный момент, - это Википедия, из статьи о sizeof:

Википедия ошибается, Skizz прав. sizeof (char) равен 1, по определению.

Я имею в виду, просто внимательно прочитал запись в Википедии , чтобы понять, что это неправильно. «кратные символы». sizeof(char) никогда не может быть ничем другим , чем «1». Если бы это было, скажем, 2, это означало бы, что sizeof(char) был вдвое больше размера char!

18
ответ дан Peter Mortensen 17 August 2018 в 05:46
поделиться
  • 1
    ... да, и мы обеспечиваем assert(sizeof(char) < sizeof(int)). Это глубокая концепция ... – Andreas Spindler 26 January 2012 в 11:02
  • 2
    Я читал, что правильный способ объявления целочисленных констант в C состоит в использовании объявления enum. – Raffi Khatchadourian 4 August 2013 в 00:08
  • 3
    Вопрос не в C ++ ..... – Pacerier 21 September 2013 в 07:56
  • 4
    Спасибо за объяснение. Исходная версия приводит к ошибке времени компиляции. Отчеты Clang & quot; индексированное значение не вл етс массивом, указателем или вектором ". Это кажется предпочтительным поведением в этом случае, хотя ваши комментарии относительно порядка оценки в макросах хорошо приняты. – Mark Harrison 28 February 2014 в 04:30
  • 5
    Я не думал о жалобе компилятора как автоматическое уведомление о некорректном типе. Спасибо! – user 28 February 2014 в 04:46
  • 6
    int noofele = sizeof(arr)/sizeof(int); только на полпути лучше, чем кодирование int noofele = 9;. Использование sizeof(arr) поддерживает гибкость при изменении размера массива. Тем не менее sizeof(int) нуждается в обновлении, если тип arr[] изменится. Лучше использовать sizeof(arr)/sizeof(arr[0]), даже если тип хорошо известен. Непонятно, почему использование int для noofele против size_t, тип, возвращаемый sizeof(). – chux 20 May 2016 в 20:50
  • 7
    Любопытно, что код использовал size_t size_of_element еще int с int n = sizeof (a) / sizeof (a[0]); , а не size_t n = sizeof (a) / sizeof (a[0]); – chux 20 May 2016 в 21:02
  • 8
  • 9
    Есть ли причина не использовать (sizeof (x) / sizeof (*x))? – seriousdev 28 March 2017 в 13:40
  • 10
    Привет @Yogeesh H T, можете ли вы ответить на вопрос о сомнении. Мне также очень интересно узнать, как int n = sizeof (a) / sizeof (a [0]) задает длину массива и почему мы не используем size_t для длины массива. Может ли кто-нибудь ответить на него? – Brain 21 July 2017 в 19:55
  • 11
    @Brain sizeof (a) дает sizeof всех элементов, присутствующих в массиве sizeof (a [0]) дает размер 1-го элемента. Предположим, что a = {1,2,3,4,5}; sizeof (a) = 20 байт (если sizeof (int) = 4 байта умножить 5), sizeof (a [0]) = 4 байта, поэтому 20/4 = 5 нет элементов – Yogeesh H T 24 July 2017 в 11:28
  • 12
    @YogeeshHT Для очень больших массивов, таких как char a[INT_MAX + 1u];, int n, как используется в int n = sizeof (a) / sizeof (a[0]);, недостаточно (это UB). Использование size_t n = sizeof (a) / sizeof (a[0]); не несет этой проблемы. – chux 21 May 2018 в 16:10
Другие вопросы по тегам:

Похожие вопросы: