C语言 简洁地声明和初始化指针(即指向int的指针)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24805673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:13:54  来源:igfitidea点击:

Declare and initialize pointer concisely (i. e. pointer to int)

cpointersdry

提问by user3849273

Given pointers to char, one can do the following:

给定指向 char 的指针,可以执行以下操作:

char *s = "data";

As far as I understand, a pointer variable is declared here, memory is allocated for both variable and data, the latter is filled with data\0and the variable in question is set to point to the first byte of it (i. e. variable contains an address that can be dereferenced). That's short and compact.

据我所知,这里声明了一个指针变量,为变量和数据分配了内存,后者被填充data\0并且有问题的变量被设置为指向它的第一个字节(即变量包含一个地址,可以被取消引用)。这是简短而紧凑的。

Given pointers to int, for example, one can do this:

例如,给定指向 int 的指针,可以这样做:

int *i;
*i = 42;

or that:

或者那个:

int i = 42;
foo(&i); // prefix every time to get a pointer
bar(&i);
baz(&i);

or that:

或者那个:

int i = 42;
int *p = &i;

That's somewhat tautological. It's small and tolerable with one usage of a single variable. It's not with multiple uses of several variables, though, producing code clutter.

这有点同义反复。它很小而且可以容忍一次使用单个变量。但是,它不会多次使用多个变量,从而导致代码混乱。

Are there any ways to write the same thing dry and concisely? What are they? Are there any broader-scope approaches to programming, that allow to avoid the issue entirely? May be I should not use pointers at all (joke) or something?

有没有什么方法可以干脆地写出同样的东西?这些是什么?是否有任何更广泛的编程方法可以完全避免这个问题?可能是我根本不应该使用指针(笑话)还是什么?

回答by Quentin

String literals are a corner case : they trigger the creation of the literal in static memory, and its access as a chararray. Note that the following doesn't compile, despite 42being an intliteral, because it is not implicitly allocated :

字符串文字是一个极端情况:它们触发静态内存中文字的创建,并将其作为char数组访问。请注意,尽管42int文字,但以下内容不会编译,因为它不是隐式分配的:

int *p = &42;

In all other cases, you are responsible of allocating the pointed object, be it in automatic or dynamic memory.

在所有其他情况下,您负责分配指向的对象,无论是在自动内存还是动态内存中。

int i = 42;
int *p = &i;

Here iis an automatic variable, and p points to it.

i是一个自动变量,p 指向它。

int * i;
*i = 42;

You just invoked Undefined Behaviour. ihas not been initialized, and is therefore pointing somewhere at random in memory. Then you assigned 42to this random location, with unpredictable consequences. Bad.

您刚刚调用了未定义的行为。i尚未初始化,因此在内存中随机指向某处。然后你分配42到这个随机位置,后果不可预知。坏的。

int *i = malloc(sizeof *i);

Here iis initialized to point to a dynamically-allocated block of memory. Don't forget to free(i)once you're done with it.

这里i被初始化为指向一个动态分配的内存块。完成后不要忘记free(i)

int i = 42, *p = &i;

And here is how you create an automatic variable and a pointer to it as a one-liner. iis the variable, ppoints to it.

这里是如何创建一个自动变量和一个指向它的指针作为单行。i是变量,p指向它。

Edit :seems like you reallywant that variable to be implicitly and anonymously allocated. Well, here's how you can do it :

编辑:似乎您真的希望隐式和匿名分配该变量。好吧,这是您的方法:

int *p = &(int){42};

This thingy is a compound literal. They are anonymous instances with automatic storage duration (or static at file scope), and only exist in C90 and further (but not C++ !). As opposed to string literals, compound literals are mutable, i.e you can modify *p.

这东西是复合字面量。它们是具有自动存储持续时间(或在文件范围内静态)的匿名实例,并且仅存在于 C90 及更高版本中(但不存在于 C++ 中!)。与字符串文字相反,复合文字是可变的,即您可以修改*p.

Edit 2 :Adding this solution inspired from another answer(which unfortunately provided a wrong explanation) for completeness :

编辑 2:另一个答案(不幸的是提供了错误的解释)的启发添加了此解决方案以确保完整性:

int i[] = {42};

This will allocate a one-element mutable array with automatic storage duration. The name of the array, while not a pointer itself, will decay to a pointer as needed.

这将分配一个具有自动存储持续时间的单元素可变数组。数组的名称虽然不是指针本身,但会根据需要衰减为指针。

Note however that sizeof iwill return the "wrong" result, that is the actual size of the array (1 * sizeof(int)) instead of the size of a pointer (sizeof(int*)). That should however rarely be an issue.

但是请注意,这sizeof i将返回“错误”的结果,即数组 ( 1 * sizeof(int))的实际大小而不是指针 ( sizeof(int*))的大小。然而,这应该很少成为问题。

回答by nishantbhardwaj2002

int i=42;
int *ptr = &i;

this is equivalent to writing

这相当于写作

int i=42;
int *ptr;
ptr=&i;

Tough this is definitely confusing, but during function calls its quite useful as:

这绝对令人困惑,但在函数调用期间它非常有用,因为:

void function1()
{
int i=42;
function2(&i);
}

function2(int *ptr)
{
printf("%d",*ptr); //outputs 42
}

here, we can easily use this confusing notation to declare and initialize the pointer during function calls. We don't need to declare pointer globally, and the initialize it during function calls. We have a notation to do both at same time.

在这里,我们可以很容易地使用这个令人困惑的符号在函数调用期间声明和初始化指针。我们不需要全局声明指针,并在函数调用期间对其进行初始化。我们有一个符号可以同时进行。

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

Though this will compile, but it will invoke undefined behaviour as you actually never initialized the pointer.

虽然这会编译,但它会调用未定义的行为,因为您实际上从未初始化过指针。

Also,

还,

char *ptr;
char str[6]="hello";
ptr=str;

EDIT: as pointed in the comments, these two cases are not equivalent. But pointer points to "hello" in both cases. This example is written just to show that we can initialize pointers in both these ways (to point to hello), but definitely both are different in many aspects.

编辑:正如评论中所指出的,这两种情况并不等效。但在这两种情况下,指针都指向“你好”。这个例子只是为了表明我们可以用这两种方式初始化指针(指向 hello),但两者在许多方面肯定是不同的。

char *ptr;
ptr="hello";

As, name of string, str is actually a pointer to the 0th element of string, i.e. 'h'. The same goes with any array arr[], where arr contains the address of 0th element.

作为字符串的名称,str 实际上是指向字符串第 0 个元素的指针,即 'h'。任何数组 arr[] 也是如此,其中 arr 包含第 0 个元素的地址。

回答by Luca Rocchi

you can also think it as array , int i[1]={42}where i is a pointer to int

您也可以将其视为数组, int i[1]={42}其中 i 是指向 int 的指针

回答by haccks

int * i;
*i = 42; 

will invoke undefined behavior. You are modifying an unknown memory location. You need to initialize pointer ifirst.

将调用未定义的行为。您正在修改未知的内存位置。您需要先初始化指针i

int i = 42;
int *p = &i;

is the correct way. Now pis pointing to iand you can modify the variable pointed to by p.

是正确的方法。现在p是指向i,你可以修改指向的变量p

Are there any ways to write the same thing dry and concisely?

有没有什么方法可以干脆地写出同样的东西?

No. As there is no pass by reference in C you have to use pointers when you want to modify the passed variablein a function.

不。因为在 C 中没有通过引用传递,所以当你想修改函数中传递的变量时,你必须使用指针。

Are there any broader-scope approaches to programming, that allow to avoid the issue entirely? May be I should not use pointers at all (joke) or something?

是否有任何更广泛的编程方法可以完全避免这个问题?可能是我根本不应该使用指针(笑话)还是什么?

If you are learning C then you can't avoid pointers and you should learn to use it properly.

如果您正在学习 C,那么您将无法避免使用指针,您应该学会正确使用它。