我们可以按如下方式在C中分配字符串:
char *string;
string = "Hello";
printf("%s\n", string); // string
printf("%p\n", string); // memory-address一个数字可以这样做:
int num = 4404;
int *nump = #
printf("%d\n", *nump);
printf("%p\n", nump);那么,我的问题是,为什么我们不能像处理字符串那样,在C中指定一个指向数字的指针呢?例如,做:
int *num;
num = 4404;
// and the rest...是什么使字符串与其他原语类型有根本区别?我对C很陌生,所以对两者之间的区别做任何解释都会很有帮助。
发布于 2019-09-03 05:55:18
为什么我们不能像用字符串那样,把指针分配给C中的数字呢?
int *num;
num = 4404;如果 4404是int的有效地址,代码就可以这样做。
整数可以转换为任何指针类型。除非如前所述,否则结果是实现定义的,可能不会正确对齐,可能不会指向引用类型的实体,而且可能是陷阱表示。 C11dr§6.3.2.3 5
如果地址没有正确对齐->未定义行为(UB)。
如果地址是陷阱->未定义行为(UB)。
试图取消引用指针是一个问题,除非它指向有效的int。
printf("%d\n", *num);在下面,"Hello"是一个字符串文本。它存在于某个地方。赋值接受字符串文字的地址并将其赋值给string。
char *string;
string = "Hello";问题是,所分配的地址对于char *是有效的。
在num = 4404;中不知道是有效的(很可能不是)。
是什么使字符串与其他原语类型有根本区别?
在C中,字符串是C库规范,而不是C语言规范。它的定义方便了解释其中的各种功能。
字符串是由第一个空字符§7.1.1 1终止并包含的连续字符序列。
基元类型是C语言的一部分。
这些语言还具有字符串文本,如"Hello"在char *string; string = "Hello";中。它们与字符串有一些相似之处,但各不相同。
我建议搜索“ISO/I 9899:2017”以找到当前C规范的草稿副本。它将回答你上周提出的10个问题中的许多。
发布于 2019-09-03 05:12:45
在C中没有" string“这样的类型。字符串是,而不是,是原始类型。字符串只是一个字符数组,以NUL字节('\0')结尾。
当你这样做时:
char *string;
string = "Hello";真正发生的是编译器很聪明,并创建了一个常量只读char数组,然后将其分配给变量string。可以这样做,因为在C中,数组的名称与指向其第一个元素的指针相同。
// This is placed in a different section:
const char hidden_arr[] = {'H', 'e', 'l', 'l', 'o', '\0'};
char *string;
string = hidden_arr;
// Same as:
string = &(hidden_arr[0]);在这里,hidden_arr和string都是char *,因为正如我们刚才所说,数组的名称等于指向其第一个元素的指针。当然,所有这些都是透明的,您实际上不会看到另一个名为hidden_arr的变量,这只是一个例子。实际上,字符串将存储在可执行文件中的某个位置,没有名称,并且该位置的地址将复制到您的string指针。
当您试图对一个整数执行相同的操作时,这是错误的,因为int *和int是不同的类型,而且您不能这样写(嗯,您可以写,但是它没有意义,也没有达到您的期望):
int *ptr;
ptr = 123;但是,您可以很好地使用一个整数数组来完成这个任务。
int arr[] = {1, 2, 3};
int *ptr;
ptr = arr;
// Same as:
ptr = &(arr[0]);发布于 2019-09-03 05:40:22
是什么使字符串与其他原语类型有根本区别?
字符串在C中似乎是一个基本类型,因为编译器理解"foo"并生成一个以空结尾的字符数组:['f', 'o', 'o', '\0']。但是C字符串仍然只是:一个字符数组。
那么,我的问题是,为什么我们不能像处理字符串那样,在C中指定一个指向数字的指针呢?
你当然可以给一个数字分配一个指针,只是一个数字不是一个指针,而数组的值是这个数组的地址。如果您有一个int数组,那么这将像字符串一样工作。比较您的代码:
char *string;
string = "Hello";
printf("%s\n", string); // string
printf("%p\n", string); // memory-address对于整数数组的类似代码:
int numbers[] = {1, 2, 3, 4, 5, 0};
int *nump = numbers;
printf("%d\n", nump[0]); // string
printf("%p\n", nump); // memory-address唯一真正的区别是编译器对字符数组有一些额外的语法,因为它们非常常见,而printf()同样为字符数组提供了格式说明符,原因也是一样的。
https://stackoverflow.com/questions/57765159
复制相似问题