我来自php背景,我正在研究这个页面http://cocoadevcentral.com/articles/000081.php之后我进入了一些关于objective-c的更难的东西
如果我输入这样的东西
typedef struct {
int lengthInSeconds;
int yearRecorded;
} Song;
Run Code Online (Sandbox Code Playgroud)
当设置Song类型的函数或变量时,它是什么意思?我知道通过将函数设置为int或者浮点数,输出将与其类型集相关.但是当我做这样的事情
Song myvariable;
or
Song myfunction(int params) { }
what type is Song setting?
Run Code Online (Sandbox Code Playgroud)
谢谢
Mik*_*one 15
我认为它可以帮助你最大程度地了解编译器头脑中发生了什么.使用你的例子:
typedef struct {
int lengthInSeconds;
int yearRecorded;
} Song;
Run Code Online (Sandbox Code Playgroud)
实际上这里发生了两件事.首先是你要定义一个匿名的struct
:
struct {
int lengthInSeconds;
int yearRecorded;
}
Run Code Online (Sandbox Code Playgroud)
这种匿名struct
可以在任何类型(例如int
或者const char*
)可以使用的地方使用.以下示例实际上是有效的,但是没有人应该编写这样的代码,因为这是一个维护噩梦:
struct {
int lengthInSeconds;
int yearRecorded;
}* GetSongInfo(const char* songName);
Run Code Online (Sandbox Code Playgroud)
这声明了一个函数,它获取具有给定名称的歌曲的信息(假设名称是唯一的,在现实生活中是无效的假设)并返回指向struct
具有其元数据的a的指针.
我将其称为"匿名struct
",因为命名的结构形式如下所示:
struct Song {
int lengthInSeconds;
int yearRecorded;
}
Run Code Online (Sandbox Code Playgroud)
现在你可以按名称引用那个结构,但不是你认为来自C以外语言的方式! 具体来说,上面的函数现在将声明为:
struct Song* GetSongInfo(const char* songName);
Run Code Online (Sandbox Code Playgroud)
请注意,类型名称struct Song
不仅仅是Song
!事实上,struct
s有一个独立的命名空间...所以语言中没有任何东西可以保证struct Song
并且Song
是同一个东西! 我不知道Objective C是否保持这种精神错乱,但我敢打赌它确实是安全的.
第二件事是你正在喂这个匿名结构typedef
. typedef
只需要一种类型,并为它定义一个您可以在以后使用的名称.所以你真的说"a Song
是struct {...}
我刚宣布的别名."
通过typedef
ing Song
,您可以改为:
Song* GetSongInfo(const char* songName);
Run Code Online (Sandbox Code Playgroud)
(是的,我知道返回会更好const Song*
,但那不是重点.)
您可能会感兴趣的是,C在其标准库中有许多typedef,旨在将平台的细节与C标准的细节分开.例如,<unistd.h>
define size_t
,表示大小的整数类型(并且是内置sizeof()
函数的返回类型),以及扩展名,应传递给函数的类型malloc()
.还有最近的<stdint.h>
头,它按位的大小定义整数类型,例如uint8_t
,对于8位无符号整数.该行<stdint.h>
可能看起来像:
typedef unsigned char uint8_t;
Run Code Online (Sandbox Code Playgroud)
由于大多数平台都有8位字符.(我已经针对某些平台进行了编程,例如TI DSP,其中a char
不是8位;通常它是16,因为处理器无法访问部分字.但是我们暂时忽略退化平台.)
最后,解释一下你的例子:
Song myvariable;
Run Code Online (Sandbox Code Playgroud)
这声明了Song
结构的存储.如果它在函数定义中,则该存储将在堆栈上分配,并在函数终止时释放.如果它在函数定义之外,它将被分配为全局.在任何一种情况下,它都是未初始化的,在C中它意味着它可以包含任何随机值.C不会跟踪未初始化的变量或将它们设置为"未初始化"或PHP和Python之类的任何变量.C也不会抛出异常.
Song myfunction(int params) { }
Run Code Online (Sandbox Code Playgroud)
这定义了一个取整数并返回Song
结构的函数.该return
函数的声明必须给出一个Song
.例如:
Song myfunction(int params)
{
Song result;
result.lengthInSeconds = GetSongLength(params);
result.yearRecorded = GetSongYear(params);
return result;
}
Run Code Online (Sandbox Code Playgroud)
此函数在堆栈上为a分配空间Song
,通过调用返回int
s的函数填充其字段,然后return
将结构复制result
到为返回值保留的空间中,最后result
在函数结束时释放存储for .通常,编译器可以优化return
语句中隐含的副本.此外,可能存在从返回值存储到最终目标的另一个(可能是优化的)副本,例如当您说:
Song foundSongInfo = myfunction(params);
Run Code Online (Sandbox Code Playgroud)
顺便说一句,struct
在堆栈上返回s是不受欢迎的,因为如果返回值适合寄存器(即简单类型),编译器通常可以更好地优化.(C++中有例外的运算符重载,但这是偏离主题的.)更好的定义是:
void myfunction(int params, Song* found)
{
found->lengthInSeconds = GetSongLength(params);
found->yearRecorded = GetSongYear(params);
}
Run Code Online (Sandbox Code Playgroud)
这避免了所有额外的副本.你这样称呼它:
Song foundSongInfo;
myfunction(params, &foundSongInfo);
Run Code Online (Sandbox Code Playgroud)
这是一种情况,其中两条线可以比一条线快.
我可能错过了一些事情,让我知道这是否有意义......
归档时间: |
|
查看次数: |
1902 次 |
最近记录: |