给定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;
这有些同义反复。使用单个变量时,它很小且可以容忍。但是,它并没有多次使用多个变量,导致代码混乱。
有没有办法干燥简洁地写同样的东西?这些是什么? 有没有更广泛的编程方法,可以完全避免这个问题?可能我根本不应该使用指针(笑话)或什么?
答案 0 :(得分:14)
字符串文字是一个极端情况:它们触发在静态内存中创建文字,并将其作为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 :添加此解决方案的灵感来自another answer(不幸的是提供了错误的解释)以确保完整性:
int i[] = {42};
这将分配具有自动存储持续时间的单元素可变数组。数组的名称while not a pointer itself将根据需要衰减为指针。
但请注意,sizeof i
将返回“错误”结果,即数组的实际大小(1 * sizeof(int)
),而不是指针(sizeof(int*)
)的大小。然而,这应该很少成为一个问题。
答案 1 :(得分:1)
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";
as,string的名称,str实际上是指向字符串第0个元素的指针,即' h'。 任何数组arr []也是如此,其中arr包含第0个元素的地址。
答案 2 :(得分:0)
int * i;
*i = 42;
将调用未定义的行为。您正在修改未知的内存位置。您需要首先初始化指针i
。
int i = 42;
int *p = &i;
是正确的方法。现在p
指向i
,您可以修改p
指向的变量。
有没有办法干燥简洁地写同样的东西?
没有。由于在C中没有通过引用传递,因此当您想要修改函数中的传递的变量时,必须使用指针。
是否有更广泛的编程方法,可以完全避免这个问题?可能我不应该使用指针(笑话)或什么?
如果你正在学习C,那么你就无法避免指针,你应该学会正确使用它。
答案 3 :(得分:0)
您也可以将其视为数组int i[1]={42}
,其中i是指向int