typedef,struct,sizeof(type),指针,随机输出,链表

本文介绍C语言中结构体的使用方法,包括结构体的定义、成员访问及内存占用情况,同时详细讲解了指针操作,如指向结构体成员的方式及链表的创建与遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值