简洁地声明和初始化指针(即指向int的指针)
给定char的指针,可以执行以下操作:
char *s = "data";
据我所知,这里声明了一个指针变量,为变量和数据分配了内存,后者填充了data\0
并且有问题的变量被设置为指向它的第一个字节(即变量包含一个可以解除引用的地址)。 那简短而紧凑。
例如,给定int的指针,可以这样做:
int *i; *i = 42;
或者那个:
int i = 42; foo(&i); // prefix every time to get a pointer bar(&i); baz(&i);
或者那个:
int i = 42; int *p = &i;
这有点同义反复。 使用单个变量时,它很小且可以容忍。 但是,它并没有多次使用多个变量,从而导致代码混乱。
有什么办法可以简洁地写出同样的东西吗? 这些是什么? 有没有更广泛的编程方法,可以完全避免这个问题? 可能是我不应该使用指针(笑话)或其他什么?
字符串文字是一个极端情况:它们触发在静态内存中创建文字,并将其作为char
数组进行访问。 请注意,以下不编译,尽管42
是一个int
文字,因为它没有隐式分配:
int *p = &42;
在所有其他情况下,您负责分配指向的对象,无论是在自动或动态内存中。
int i = 42; int *p = &i;
这里i
是一个自动变量,p指向它。
int * i; *i = 42;
您刚刚调用了未定义的行为。 i
还没有被初始化,因此在内存中随意指向某处。 然后你为这个随机位置分配了42
,结果不可预测。 坏。
int *i = malloc(sizeof *i);
这里i
被初始化为指向动态分配的内存块。 一旦你完成它,不要忘记free(i)
。
int i = 42, *p = &i;
以下是如何创建一个自动变量和指向它的指针作为单行。 i
是变量, p
指向它。
编辑:似乎你真的希望隐式和匿名分配该变量。 那么,你可以这样做:
int *p = &(int){42};
这件东西是复合文字。 它们是具有自动存储持续时间的匿名实例(或在文件范围内是静态的),并且仅存在于C90中(并且不存在于C ++中)。 与字符串文字相反,复合文字是可变的,即你可以修改*p
。
编辑2:添加此解决方案的灵感来自另一个答案 (不幸的是提供了错误的解释)完整性:
int i[] = {42};
这将分配具有自动存储持续时间的单元素可变数组。 数组的名称虽然不是指针本身 ,但会根据需要衰减为指针。
但请注意, sizeof i
将返回“错误”结果,即数组的实际大小( 1 * sizeof(int)
)而不是指针的大小( sizeof(int*)
)。 然而,这应该很少成为一个问题。
你也可以认为它是数组, int i[1]={42}
其中i是指向int的指针
int * i; *i = 42;
将调用未定义的行为。 您正在修改未知的内存位置。 您需要首先初始化指针i
。
int i = 42; int *p = &i;
是正确的方法。 现在p
指向i
,你可以修改p
指向的变量。
有什么办法可以简洁地写出同样的东西吗?
不可以。因为在C中没有通过引用传递,所以当你想修改函数中传递的变量时,你必须使用指针。
有没有更广泛的编程方法,可以完全避免这个问题? 可能是我不应该使用指针(笑话)或其他什么?
如果您正在学习C,那么您无法避免指针,您应该学会正确使用它。
int i=42; int *ptr = &i;
这相当于写作
int i=42; int *ptr; ptr=&i;
这很难让人感到困惑,但在函数调用期间它非常有用:
void function1() { int i=42; function2(&i); } function2(int *ptr) { printf("%d",*ptr); //outputs 42 }
在这里,我们可以轻松地使用这种令人困惑的符号来在函数调用期间声明和初始化指针。 我们不需要全局声明指针,并在函数调用期间初始化它。 我们有一个记号可以同时做两个。
int *ptr; //declares the pointer but does not initialize it //so, ptr points to some random memory location *ptr=42; //you gave a value to this random memory location
虽然这会编译,但它会调用未定义的行为,因为你实际上从未初始化指针。
也,
char *ptr; char str[6]="hello"; ptr=str;
编辑:正如评论中所指出的,这两种情况并不相同。 但指针在两种情况下都指向“你好”。 编写这个例子只是为了表明我们可以用这两种方式初始化指针(指向你好),但两者在很多方面都是不同的。
char *ptr; ptr="hello";
因为,string的名称,str实际上是指向字符串的第0个元素的指针,即’h’。 任何数组arr []也是如此,其中arr包含第0个元素的地址。