微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c中的int指针和char指针之间有区别吗? 简短答案:否 char * c =“ c”是什么? int* a = 10呢?一个例子

如何解决c中的int指针和char指针之间有区别吗? 简短答案:否 char * c =“ c”是什么? int* a = 10呢?一个例子

我是C语言的新手,在理解指针时遇到了麻烦。我感到困惑的部分是关于char *int *

例如,我们可以直接为char分配一个指针,例如

char *c = "c";并不会出错。

但是,如果像我刚才那样为int分配一个指针,例如int * a = 10;

会出错。我需要在内存中留出一个额外的空间来为int分配一个指针,

int *b = malloc(sizeof(int)); *b = 20; free(b); ...

谁能告诉我为什么?

解决方法

我认为您误解了什么是指针及其含义。在这种情况下:

int* a = 10;

您说的是“创建一个指向int的指针,并将其指向文字存储位置0x0000000A(10)。

与以下不同:

int n = 10;
int* a = &n;

这是“创建指向int的指针,并将其指向n的存储位置。

如果要动态分配此值:

int* a = malloc(sizeof(int));
*a = 10;

翻译为“创建指针(指向int)并将其瞄准刚分配的内存块,然后将分配给该位置10

通常,您永远不会分配单个int,而是会为一个数组分配一堆a[0],在这种情况下,您将其称为a[n-1]n大小为*(x + y)的数组。在C中,x[y]通常与*(x + 0)相同,换句话说,*x只是x[0]2020-10-02T20:03:19.389Z 09b6f1b2-d80a-15e1-9531-f74182e95c1e ERROR Invoke Error { "errorType":"Error","errorMessage":"ENOENT: no such file or directory,open '/mnt/efs/newfile.txt'","code":"ENOENT","errno":-2,"syscall":"open","path":"/mnt/efs/newfile.txt","stack":[ "Error: ENOENT: no such file or directory," at Object.openSync (fs.js:458:3)"," at Object.writeFileSync (fs.js:1355:35)"," at WriteFile (/var/task/src/apis/permissions/isallowed.js:70:8)"," at IsAllowedInPolicy (/var/task/src/apis/permissions/isallowed.js:52:5)"," at Runtime.exports.handler (/var/task/src/apis/permissions/isallowed.js:16:28)"," at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)" ] }

,

在您的示例中,您没有将c发送到字符'c'。您使用了"c",它是字符串文字。 对于字符串文字,其工作方式如https://stackoverflow.com/a/12795948/5280183中所述。

,

"c"这样的字符串文字实际上是一个数组表达式("c"的类型是“ char的2元素数组)。

除非它是sizeof&运算符的操作数,否则它是用于在声明中初始化字符数组的字符串文字,即类型为T的数组的表达式“将被转换,或“衰减”为“指向T的指针”类型的表达式,其值将为数组第一个元素的地址。

所以当你写

char *c = "c"; 

大致相当于写作

char string[] = "c";
char *c = &string[0];

您正在将指针分配给指针,因此编译器不会抱怨。

但是,当你写

int *a = 10;

您要为指针分配int值,并且类型不兼容,因此编译器会抱怨。指针不是整数;它们可能具有整数表示形式,但这不能保证,并且大小将与int相同。

,

初始化中,右侧(RHS)表达式必须是声明的变量或可以转换为声明的变量的类型。

如果愿意

char *cp = ...
int *ip = ...

然后,...中的内容必须可转换为指向char指针或指向int 指针。另外请记住,char是单个字符。

现在,"abc"是C中的一种特殊语法-字符串文字,用于创建由(许多)不可变字符组成的数组。它的类型为char [size],其中size是文字中的字符数加上一个用于终止空字符的字符数。因此"c"的类型为char [2]。不是char。 C语言中的数组被隐式转换指向第一个元素的指针,其类型为“指向元素类型的指针”。即"c"中类型为char [2]的{​​{1}}被隐式转换为类型char *cp = "c";,该类型指向 two first >两个字符数组中的字符char *c。它也很方便,类型为\0,现在我们有了char *

对于char *cp = (something that has type char * after conversions);,您正在尝试将整数值传递给指针。这没有道理。

指针保存一个地址。如果您要问福尔摩斯的地址,答案是贝克街221号。现在您要做的是“ Sherlock Holmes的地址是我今天早上为他拍的这张照片”。

int *编写的相同错误代码将是

char *

它会给您完全相同的错误,证明char *cp = 'c'; // or more precisely `char *p = (char)'c'; char *cp可以正常工作。


不幸的是,C没有整数字符串的 int *cp 文字,尽管从C99开始,您可以编写:

int

int *ip = (int[]){ 5 };

同样,您始终可以将const int *ip = (const int[]){ 5 }; char *指向该类型的单个对象:

char a ='c'; char * pa =&a; 整数b = 42; int * pb =&b;

现在我们可以说int *a指定相同 *pa对象char,同样地,a和{ {1}}指定相同 b对象*pb。如果您更改int,则将更改b,反之亦然; *paa也是如此。

,

c中的int指针和char指针之间有区别吗?

简短答案:否

在过去的几十年中,C中的所有指针均被创建。在某些时候,由于称为内存模型的原因,在某些平台(例如Windows)中,指针的大小不同。

今天,编译器将代码设置为使用32位或64位或任何大小的指针,具体取决于平台,但一旦设置,所有指针均相等。

不相等的是指针指向的东西,就是您感到困惑。

  • 考虑一个void*指针。 malloc()在C中分配内存。它总是返回一个void*指针,然后将其强制转换为所需的任何内容
  • sizeof(void*)sizeof(int*)相同。并且与sizeof(GiantStruct*)相同,在64位编译器中为8字节或64位

char * c =“ c”是什么?

  • 您必须问自己什么是"c"。是char[2]。这是一个字符串文字。系统将在内存中的某个位置分配至少2个字节的区域,并在其中放置一个'c'和一个零,因为字符串文字以NULL终止C,因此请将该地址放入分配给指针c的地址。

int* a = 10呢?

  • 是同一回事。在进入操作系统之前,还可以。a是什么? a是指向int*的{​​{1}}指针。 int是什么? *a。在哪个地址? int。好吧,事实是系统不会仅仅因为您设置了指向该地址的指针就允许您访问该地址。在80年代,您可以。如今,关于此的规则非常严格:您只能访问分配给进程的内存。只要。因此,系统会在您尝试访问时立即中止您的程序。

一个例子

如果你写

10

系统将分配一个300字节的区域,获取该区域的地址并将其写入分配给a的地址。当您写入 int* a = malloc(300); 时,系统会将这个值写入该地址的前*a=3456个字节。

您可以确定全部写入300,但是您必须在某种程度上操纵指针以指向区域内部。仅在该区域内。 实际上,C语言就是为此目的而设计的。

让我们在分配给a的300字节区域的末尾写“ c”:

sizeof(int)

然后看

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    char* c = "c";
    int* a = (int*)malloc(300);
    *a = 3456;
    printf("Area content is %d\n",*a);
    char* pToEnd = (char*)a + 298;
    *(pToEnd) = 'c';
    *(pToEnd + 1) = 0;
    printf("At the end of the 300-byte area? [Should be 'c'] '%s'\n",pToEnd);
    printf("The pointer c points to '%s'\n",c);
    //*c = 'x'; // error: cancel program
    c = pToEnd;
    printf("The pointer c now points do the end of the 300-byte area:'%s'\n",c);
    free(a);
    return 0;
};

还要注意,一旦尝试覆盖示例中的Area content is 3456 At the end of the 300-byte area? [Should be 'c'] 'c' The pointer c points to 'c' The pointer c now points do the end of the 300-byte area:'c' 指针c,程序也会取消。这是一个只读区域---参见第14行的注释。但是您可以在示例中将char指向该区域内部并使用它,因为指针本身不是恒定的。

在上述示例中,当您编写c时,对字符串文字的访问将永远丢失。从某种意义上讲是内存泄漏,但这是静态分配的区域。 泄漏不是区域,而是地址。

还要注意,即使结尾c = pToEnd free(a) a也会释放所有300字节

,

您问题的直接答案是C语言是一种严格的类型化语言。在生成机器代码之前,编译器会检查一些可能的错误。类型不同,这就是编译器要知道的全部内容。

但是从位字节的角度来看,C语言与上面的两个指针没有什么区别。

看看your code with online compiler

void main(){
 int * a = 10; /* <= this presumably gives you an error. */
}

我所做的是复制粘贴的代码,使您看到错误。 在线编译器发出了警告,而不是错误。甚至更多。将C的标准更改为c17,您仍然会得到警告。

在SO上已广泛讨论了有关将字符串文字分配给指针的注释。它应该有一个不同的主题。

总结一下。对于C语言,以上两个指针没有任何有意义的区别。是用户,他有责任知道其程序中存储器的布局。总而言之,该语言被设计为可在线性内存上运行的高级工具。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。