LINUX.ORG.RU

[c] char * OR char []

 


0

1

Какая разница между объявлением в header'e

static char str[] = "text";

и

static char *str = "text";

?

★★

Последнее исправление: bk_ (всего исправлений: 1)

Абсолютно одно и то же, в C безразмерные массивы и указатели равнозначны.

Вы даже можете написать такой код:

char text[];
text = (char *) malloc(strlen);

И все будет прекрасно.

whoami
()
Ответ на: 4.2 от yoghurt
#include <stdio.h>

static char a[] = "text";
static char *b  = "text";

int main (int argc, char *argv[]) {
    printf ("size of a is %d\n"
            "size of b is %d\n",
            sizeof (a), sizeof (b));
    return 0;
}
yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt
#include <stdio.h>
#include <string.h>

static char a[] = "text";
static char *b  = "text";

int main (int argc, char *argv[]) {
    printf ("size of a is %d [%d]\n"
            "size of b is %d [%d]\n",
            sizeof (a), strlen(a), sizeof (b), strlen(b));
    return 0;
}

>> ./a.out 
size of a is 5 [4]
size of b is 4 [4]

Как тогда обеспечивается '\0' для строки b? Компилятором «за кадром»? Ведь я ее могу использовать в функциях из string.h, а, следовательно, нулевой символ обязан быть.

bk_ ★★
() автор топика
Ответ на: 4.2 от yoghurt

Нифига.

После такого объявления
static char a[] = «text»;
static char *b = «text»;
можно написать
b = a;
Но нельзя
a = b;

svu ★★★★★
()
Ответ на: комментарий от bk_

>Как тогда обеспечивается '\0' для строки b?

Он там есть, как и в любом другом строковом литерале. Не забывай, что b - указатель. Первая 4 для b говорит о том, что размер указателя в твоей системе - 4 байта.

Ведь я ее могу использовать в функциях из string.h, а, следовательно, нулевой символ обязан быть.

И он там есть

yoghurt ★★★★★
()
Ответ на: комментарий от svu

>>static char *b = «text»;

+ в этом объявлении - константная строка, нельзя будет написать

b[0] = 'a';

alex_custov ★★★★★
()

K&R 94page

bk_ ★★
() автор топика

>static char str[] = «text»;
создается статический массив символов
выделяется памяти: 4 + 1 = 5 байт

static char *str = «text»;

создается статический указатель на массив символов, который размещается неподалеку
выделяется памяти: 4 + 4 + 1 = 9 байт

xydo ★★
()
Ответ на: комментарий от bk_

>Как тогда обеспечивается '\0' для строки b? Компилятором «за кадром»?

пример наибредовейший. a и b имеют разные типы. соответственно, sizeof(char []) и sizeof(char *) - две принципиально разные вещи.

sizeof(b) - размер указателя, но никак не массива, на который он указывает.

xydo ★★
()
Ответ на: комментарий от wlan

>Ну а суть этого одна и та же
не одна и та же!
указатель - это прежде всего переменная, которая, помимо той памяти, на которую указывает, также занимает память.

xydo ★★
()
Ответ на: комментарий от wlan

>массивы переводит в указатели
вы читали не те книги. правильней сказать: переводит имя массива в адрес первого элемента.
дополнительной переменной для хранения адреса тут не создается.

xydo ★★
()
Ответ на: комментарий от xydo

в смысле классической C-строкой. с \0 в конце

xydo ★★
()
Ответ на: комментарий от xydo

Я читал КиР, и наверное просто не правильно сформулировал, спасибо, теперь буду учитывать эту тонкость

wlan ★★
()
Ответ на: комментарий от wlan

КиР, конечно, хорошо, но, учитывая, что на форуме периодически появляются темы а-ля «не компилиться пример из K&R», я бы проверял неочевидные вещи на практике :)
хоть это и мелочи, они способствуют правильному пониманию логики компилятора.

xydo ★★
()

Почитай Expert C Programming by Peter van der Linden

mukoh
()
Ответ на: комментарий от xydo

Да спасибо

Почитай Expert C Programming by Peter van der Linden

у меня оно даже вроде на фтп где-то было, надо полистать

wlan ★★
()

Для глобальных переменных есть разница, для параметров функции - нет.

#include <stdio.h>

static char a[] = "string";
static char *b  = "string";

int test(char *c, char d[]) {
    return printf( "%d, %d, %d, %d\n",
        sizeof (a), sizeof (b), sizeof (c), sizeof (d) );
}

int main () {
    return test( 0, 0 );
}
$ g++ a.cpp && ./a
7, 4, 4, 4
zzf
()
Ответ на: комментарий от hunt

Действительно используется - при управлении версиями.

После сборки можно узнать какой версии emess.h использовался при сборке в каком бинарнике.

Возможно даже добавляется автоматически системой управления версиями.

Раньше все так делали.

anonymous
()
Ответ на: комментарий от namezys

Этот вопрос действительно в c-faq уже сто лет в обед как обсужден, все различия там описаны.

anonymous
()
Ответ на: комментарий от anonymous

да, и lint тут ни при чем, как вы понимаете.

anonymous
()
Ответ на: комментарий от zzf

>Для глобальных переменных есть разница, для параметров функции - нет.
кто ж вас плодит-то.
сделай дамп стека для
foo(char *)
и для
foo(char[])
вдруг чего новое увидишь :)

xydo ★★
()
Ответ на: комментарий от anonymous

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

hunt
()
Ответ на: комментарий от xydo
#include <stdio.h>

static const char* fmt;
static const char* str = "string";

void func(const char str1[], const char* str2)
{
	printf(fmt);
}

int main(int argc, char* argv[])
{
	fmt = argv[1];
	
	printf("str: %p\n", str);
	
	func(str, str);
	puts("");
	
	return 0;
}
hunt@zeus:~/temp$ ./stack1 "%08x %08x %08x %08x %08x %08x %08x %08x %08x"
str: 0x8048540
00913160 00a224e0 08048547 bf880bc4 00a21ff4 bf880bd8 0804846d 08048540 08048540

Вроде одинаково. Или я что-то не так делаю?

hunt
()
Ответ на: комментарий от xydo

> сделай дамп стека для

void foo1(unsigned, char *x, unsigned) {}

void foo2(unsigned, char x[], unsigned) {}

int main() {
    foo1( 0xAAAAAAAA, 0, 0xBBBBBBBB );
    foo2( 0xCCCCCCCC, 0, 0xDDDDDDDD );
    return 0;
}

Дамп:

foo1:
0x0022ccf0  AA AA AA AA 00 00 00 00 BB BB BB BB EA 10 40 00  ..............@.

foo2:
0x0022ccf0  CC CC CC CC 00 00 00 00 DD DD DD DD EA 10 40 00  ..............@.

Also, срочно в школу - доучиваться.

zzf
()
Ответ на: комментарий от anonymous

На машине с размером указателя 4 байта выделится память под указатель (4 байта) и память для хранения 4 символов и 1 символа завершающего нуля. Итого имеем: 4 + 4 + 1 = 9 байт.

Другой анонимус

anonymous
()
Ответ на: комментарий от anonymous

Потому что система 64 битная, и размер указателя соответствующий?

hunt
()
Ответ на: комментарий от anonymous

Я для таких неучей как ты, специально уточнил про машину 4-байтным указателем. Да и товарищ тебе уже указал на разрядность твоей машины.

Тот самый другой анонимус

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.