Demo1:
1.typedef在已有数据类型的基础上定义自己的类型名称(别名)
//给int起一个别名(外号)MyInt
typedef int MyInt;
//1.适配不同机器,增加可移植
//2.增加代码的可读性
//3.减少代码量
typedef char Color;
typedef Color OldColor;//char有Color和OldColor两个别名
typedef unsigned long int ULong;
2.//类型struct表示结构类型定义和结构变量说明,通知系统如何分配空间
//类型,通知系统如何分配空间
struct Student{
int age;//成员
char name[10];
float height, weight;
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
Student stu0; //定义变量,与 struct Student stu0; 等同
}
return 0;
}
3.//sizeof(type)用于返回指定类型所占内存空间。
//类型的定义在上面
NSLog(@"%zu",sizeof(struct Student));
ULong ui = 1234;
NSLog(@"%zu",sizeof(ui));
NSLog(@"%zu",sizeof(OldColor));
输出
2015-07-23 20:07:21.335 typedef[937:34553] 16
2015-07-23 20:07:21.336 typedef[937:34553] 8
2015-07-23 20:07:21.336 typedef[937:34553] 1
PS:对于自定义的数据类型struct s{ long a;char b;};,返回的就是该结构体内所有基本数据类型所占字节数的总和.考虑到现在机器对于数据存储一般都要求按边界对齐(这样可以减少读取次数),如果按字对齐的话,那sizeof(struct s)也有可能总和增大
Demo2:
1.指针,变量
/*
例:指向age的方法:
1)struct Student stu0;//定义变量时
stu0.age
2)struct Student *pStu = &stu0; //定义指针变量时
pStu->age
3)struct Student stu1;
pStu->next = &stu1;
stu1.age
4)stu0.next->age
5)pStu->next->age //stu0.next 与 pStu->next 等同
*/
Student *pHead;//定义指针变量
Student stu0; //定义变量,与 struct Student stu0; 等同
stu0.age = 100;
pHead = &stu0;
Student stu1;
stu1.age = 101;
stu1.next = NULL;
stu0.next = &stu1;
Student stu2;
stu2.age = 102;
stu2.next = NULL;
stu1.next = &stu2;
//stu1.age
NSLog(@"pHead->next->age:%d", pHead->next->age);
//stu0 > stu2 , stu2.age
NSLog(@"pHead->next->next->age:%d", pHead->next->next->age);
//与pHead->next->next->age等同
NSLog(@"(*((*((*pHead).next)).next)).age:%d",(*((*((*pHead).next)).next)).age);
NSLog(@"----5----");
//单向链表//stu0 > stu3 > stu2
//NSLog(@"%d",(*((*((*pHead).next)).next)).age);
NSLog(@"pHead->next->next->age: %d", pHead->next->next->age);
NSLog(@"----6----");
//遍历链表//stu0 > stu3 > stu2
Student *pointer = pHead;
while (pointer) {
NSLog(@"age: %d", pointer->age);
pointer = pointer->next;
}
输出:
2015-08-01 21:28:03.087 Struct[1156:50282] pHead->next->age:101
2015-08-01 21:28:03.087 Struct[1156:50282] pHead->next->next->age:102
2015-08-01 21:28:03.087 Struct[1156:50282] (((((*pHead).next)).next)).age:102
2015-08-01 21:28:03.091 Struct[1156:50282] —-5—-
2015-08-01 21:28:03.097 Struct[1156:50282] pHead->next->next->age: 102
2015-08-01 21:28:03.098 Struct[1156:50282] —-6—-
2015-08-01 21:28:03.098 Struct[1156:50282] age: 100
2015-08-01 21:28:03.098 Struct[1156:50282] age: 103
2015-08-01 21:28:03.099 Struct[1156:50282] age: 102
2.随机输出数字
//[0, 5)随机输出
NSLog(@"行:%d", arc4random_uniform(5) + 1);
NSLog(@"列:%d", arc4random_uniform(8) + 1);
//随机输出[0,9] arc4random()
NSLog(@"rand: %u", arc4random()%10);
输出:
2015-08-01 21:28:03.085 Struct[1156:50282] 行:2
2015-08-01 21:28:03.086 Struct[1156:50282] 列:6
2015-08-01 21:28:03.087 Struct[1156:50282] rand: 1
3.链表
int main(int argc, const char * argv[]) {
@autoreleasepool {
//链表
//1. 有序
//2. 内存中不一定排列在一起
//打印地址
NSLog(@"%p", pHead->next->next);
NSLog(@"----7----");
NSLog(@"%zu", sizeof(struct Student));
struct Student student;
// student.name = "Zhangsan";错误,类型不同,数组不能赋值
strcpy(student.name, "Zhangsan");
student.age = 12;
student.height = 1.5;
student.weight = 60;
struct Student student1;
student1 = student;
NSLog(@"student1.name:%s", student1.name);
NSLog(@"student1.age:%d", student1.age);
NSLog(@"----9----");
char name1[20] = "Lisi";
char name2[20];
// name2 = name1;
strcpy(name2, name1);//复制
NSLog(@"name2:%s", name2);
NSLog(@"----10----");
Student *pStu = &student;
NSLog(@"(*pStu).name:%s", (*pStu).name);
NSLog(@"pStu->name:%s", pStu->name);//通过指针访问成员,等同(*pStu).name
}
return 0;
}
输出:
2015-08-01 21:28:03.099 Struct[1156:50282] 0x7fff5fbff7d0
2015-08-01 21:28:03.099 Struct[1156:50282] —-7—-
2015-08-01 21:28:03.100 Struct[1156:50282] 40
2015-08-01 21:28:03.101 Struct[1156:50282] student1.name:Zhangsan
2015-08-01 21:28:03.101 Struct[1156:50282] student1.age:12
2015-08-01 21:28:03.101 Struct[1156:50282] —-9—-
2015-08-01 21:28:03.101 Struct[1156:50282] name2:Lisi
2015-08-01 21:28:03.101 Struct[1156:50282] —-10—-
2015-08-01 21:28:03.102 Struct[1156:50282] (*pStu).name:Zhangsan
2015-08-01 21:28:03.102 Struct[1156:50282] pStu->name:Zhangsan
代码解析:结构体中数组成员赋值
student.name = “Zhangsan”;不能编译
原因:
“Zhangsan”字符串在编译后会放在常量区,引用这个字符串全部会被替换成引用指向该字符串的指针处理。所以如果student.name=”Zhangsan”,那么就相当于把一个指针赋值给数组,它们类型不同,是不会通过编译的。
strcpy(student.name, “Zhangsan”);能编译成功
原因:
1.Zhangsan.name 和 “Zhangsan”的类型一致
1).Zhangsan.name大概等同于&Zhangsan.name[0]
2).直接用字符串,系统处理为静态指针
即Zhangsan.name 和 “Zhangsan”的类型都是 char *!
2.详解Zhangsan.name 和 “Zhangsan”
1).Zhangsan.name
char name[15]做了这样一件事:他在进程的堆栈空间里分配了15个连续的char类型空间,并让指针name指向这段空间的第一个位置。既然name指向第一个位置,它当然是char *类型了。在C语言里,数组和指针是不分家的。建议楼主认真阅读《The C Programming Language:第五章 指针与数组》(PS:你看看,Kernighan和Ritchie把指针和数组都归在一章里了,可见它俩之间的关系有多紧密。)
2).”Zhangsan”
这个比较复杂,容我细细道来。”Zhangsan”是字符串,不错!但是它不是一般的字符串,它是字符串常量。所谓常量,就是在编译阶段就可以确定其值,并不会改变其值那一类变量。一段C程序被编译成机器码以后,当它执行的时候,内存是这样分配的:
如图:
代码区就是C代码被编译以后的机器代码;
栈区用来分配函数内的自动变量;
堆区用来分配全局的可变变量(注意!“可变变量”这个词是我自造的,其实可变变量就是一些全局的空间,这些空间的内容是可以被改变的。)。
那么,静态数据区是干什么的呢?答:它用来存放那些内容不可改变的变量的(说白了,这些变量就是常量!)。
所以呢,针对下面代码代码,变量分配是这样的:
int
main(int argc , char *argv[])
{
struct student Zhangsan;
memset (&Zhangsan, 0, sizeof(Zhangsan));
Zhangsan.num = 7;
strcpy(Zhangsan.name, “Zhangsan”);
return 0;
}
堆区:Zhangsan
栈区:argc,argv
静态数据区:”Zhangsan”
so,”Zhangsan”字符串是无名的。”Zhangsan”自己就是自己的名字——它的类型就是char*.
总结一句:字符串常量的值就是该字符串常量的首字符地址!
强调一句:字符串常量的在静态数据区,其内容是不能被改变的!(strcpy(
“Zhangsan”,string)是个严重的错误哦!)
参考自http://www.360doc.com/content/12/0328/09/8302596_198486566.shtml