ObjectiveC学习准备__C语言4

本章重点:结构体,指针。

我们一起来学习结构体..

为什么需要结构体呢  因为变量只能储存单一类型的数据 如果有关联的多种类型数据需要储存就会很乱,

比如说要存一个学生信息  名字,学号,电话,住址,成绩,班级 ;这些类型不同却又互相关联的数据我们用结构体来储存

首先结构体的定义与属性的访问

#include <stdio.h>
struct student{
    char name[20];
    int stucode;
}stu1;
int main(){
  struct student stu;
     stu.stucode=20;
     stu1.stucode=10;   
     printf("%d\n",stu.stucode);
     printf("%d\n",stu1.stucode);

}

从上面可以看到结构体的定义方式

1) 先定义结构体类型,再定义结构体类型变量:也就是stu;

2 ) 定义结构体类型同时定义结构体类型变量:也就是stu1;

3) 直接定义结构体类型变量:(这种方式一般都是一次性定义 很少使用):

struct
{
    char name[20];
   int stucode;
} stu3;

该定义方法由于无法记录该结构体类型,所以除直接定义外,不能再定义该结构体类型变量

方法1,2之后想要声明变量都需要写struct student 变量名;是不是很麻烦?

这里有个 typedef  语法为 typedef  类型  你想要的变量名;

#include <stdio.h>
typedef int I;
int main(){
     I i=1;
     printf("%d\n",i);       
}

再来看看结构体

#include <stdio.h>
typedef struct{
    char name[20];
    int stucode;
} Stu;
int main(){
  Stu stu;
     stu.stucode=20;
     printf("%d\n",stu.stucode);
}

是不是简单多了呢?

继续学习...下面是C里面比较难一些的  指针

指针的作用

指针可以用来有效地表示复杂的数据结构,可以用于函数参数传递并达到更加灵活使用函数的目的.使C语言程序的设计具有灵活、实用、高效的特点。

指针不仅仅是C语言的灵魂,运用得好更是事半功倍,让你写出的程序更简洁!(这个度娘说的更清楚);

指针类型的定义:类型 * 变量名;

内存其实分成很多空间,每个空间都有其地址,地址从1开始排也许能排几千亿甚至更多,

指针默认空间大小是八个字节,我们测试一下

#include <stdio.h>
int main(){
  int a=10;
  int * p;
 printf("%d\n",sizeof(int));
 printf("%d\n",sizeof(p));            
}

可能有人得到的是4个字节,因为你是32位系统,或者是32位的MinGW,64位的则是八个字节

指针到底怎么用呢?指针指向的是一个地址 我们都知道通过&变量名就能访问一个变量的地址,所有要指针指向变量的数据可以这样写

#include <stdio.h>
int main(){
 int a=10;
 int b=20; 
 int * p=&a;
  printf("%p\n",&a);
  printf("%p\n",p);   
  printf("%d\n",a);
  printf("%d\n",*p);
  p=&b;
  printf("%d\n",*p);
  printf("%p\n",&b);
  printf("%p\n",p); 
  *p=30;
  printf("%d\n",*p);
  printf("%p\n",&b);
  printf("%p\n",p);
}

通过以上代码可以了解到指针的简单使用*p能访问指向内存地址中的值,改变*p就能改变齐指向内存地址中的值,而p则是该指针指向的一个内存地址,改变p则改变地址

*p=30;等价于b=30;

以上都是指向变量的指针,下面看指向数组的指针

#include <stdio.h>
int main(){
  int a[20];
  int* p=a;
  *p=20;
  printf("%p\n",p);
  p++;
  *p=30;
  printf("%p\n",p);
  p++;
  *p=40;
  printf("%p\n",p);
  printf("%d\n",a[0]);
  printf("%d\n",a[1]);
  printf("%d\n",a[2]);              
}

通过以上例子不难看出a本身就是数组的首地址,所以给指针赋值时没有增加&符号

根据每次p地址的输出可以看出p++并不是在p地址+1,而是在p地址加上一个int*p的大小  也就是4,每次赋值之后数组都往后挪一位;

指针用作函数参数比较多

#include <stdio.h>
void print(int *start,int* end){
    while(start<end){
        printf("%d\n",*start++);
    }
}
int main(){
  int a[]={3,3,3,2,4,5,3,2,4,5};
  int length=sizeof(a)/sizeof(a[0]);
  print(a,a+length);
}

这里定义了一个输出函数 能把传入的数组循环输出,参数是数组开始的地址和结束的地址,有人可能有疑问:首先length是什么?length是整个数组大小除以单个数的大小,

所以length是该数组的长度 a:则是数组开始的地址也就是首地址,a+length 数组长度就是数组结束地址,

最后解释下while循环内的输出语句

printf("%d\n",*start++);
等价于
printf("%d\n",*start);

start++;
因为*运算符优先权高于++所以写在一起是先取*start输出在执行start++;

当然指针作为一个类型也可以当函数返回值..我们知道C语言函数返回值是没有数组的,所以我们只能返回数组的首地址

#include <stdio.h>
int* print(int *a){
    //处理过函数代码
    return a;
}
int main(){
  int a[]={3,3,3,2,4,5,3,2,4,5};
  int*p=print(a);
}

程序运行完之后指针p是指向数组a的首地址的(处理函数代码自己按需求脑补)

前面讲了那么多一直用的都是int类型指针  事实上指针类型有很多(char,float,double....)  指针要根据你给的类型判断内存中多少个字节放在一起处理

这里有个指针类型是 void 这是变量所没有的,那么void怎么用呢?

#include <stdio.h>
int main(){
     int a=2;
     float b=2.1;
     void*p;
     p=&a;
     printf("%d\n",*(int*)p);    
     p=&b;
     printf("%lf\n",*(float*)p);
}

void指针可以指向任何类型数据但如果你想使用void指针的数据就必须进行强转  如上面代码一样  原本是什么类型 取出时就强转成什么类型。

原文地址:https://www.cnblogs.com/pengser/p/4915366.html