数组的使用
char letters[5] = {'a','b','c','d','e'};
//如果将[]中的数字隐去,则按照{}中元素的具体数目进行数组分配
char letters[] = {'a','b','c','d','e'};
int numbers[300] = {[9]=1,[3]=7,[1]=29};//任意指定,顺序可以打乱
//如果这里[]中的数字隐去,则默认按照最大的下标来分配数组元素数目,即numbers只有10个元素
int numbers[] = {[9]=1,[3]=7,[1]=29};//任意指定,顺序可以打乱
char word[] = {'H','e','l','l','o','\0'};
NSLog(@"%s",word);
//输出的是“Hello”,因为NSLog会持续显示字符,直到遇到空字符
将函数声明写在文件的开头是一个好习惯,即使调用的函数在前面已经定义,也要尽量把该函数在文件头进行声明一下,这样才能保证编译的正确性。
块(Block)
块定义在函数或者方法的内部,相当于一个简单的内嵌函数,它可以访问块之外函数之内的任意变量
(void)(^printmessage)(void)=
^(void)//括号里面的是传入的参数类型
{
NSLog(@"Hello");
};//不要忘记这个分号
...
...
printmessage();//调用方式不变
#import<Foundation/Foundation.h>
int main(int argc, char const *argv[])
{
@autoreleasepool
{
int foo = 10;//输出结果为10,说明块方法在定义的时候就已经捆绑了变量的值
__block int foo = 10;//输出结果为15,说明块方法在运行的时候才捆绑变量的值
void(^printFoo)(void)=
^(void)
{
NSLog(@"foo = %i",foo);
};
foo = 15;
printFoo();
}
return 0;
}
#import<Foundation/Foundation.h>
int main(int argc, char const *argv[])
{
@autoreleasepool
{
__block int foo = 10;//只有定义成块变量,foo才可以在块中更改值
void(^printFoo)(void)=
^(void)
{
NSLog(@"foo = %i",foo);
foo = 20;
};
foo = 15;
printFoo();//输出15
NSLog(@"foo = %i",foo);//输出20
}
return 0;
}
C语言的语法补充
//
// main.c
// helloword
//
// Created by 修宇亮 on 14-7-16.
// Copyright (c) 2014年 修宇亮. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
struct student{
int age;
int grade;
char *name;
};
#define SIZE_OF_ARRAY(a) sizeof(a)/sizeof(a[0])
#define HELLO(name) void name##girl(){ \
printf("hello girl"); \
}// \起到续行的作用
#define MYFUNC(name) void name##INIT()
MYFUNC(xyl);
HELLO(xyl);
void xylINIT(){printf("xyl is so cool!");}
一个验证##的实例
#import<Foundation/Foundation.h>
#define INITNAME() {\
printf("Hello xyl1\n");\
}
#define HELLONAME(name) name##hello()//这里不要写上void,会无法连接到xylhello()
void xylhello(){
printf("Hello xyl2\n");
}
int main(int argc, char const *argv[])
{
INITNAME();
HELLONAME(xyl);
return 0;
}
typedef int long_byte_four;//给数据类型重新命名类型名
int a = 12;
int b = 34;
int *p1 = &a;
int *p2 = &b;
void swap01(int,int);
void swap02(int *,int *);
void swap03(int **,int **);
void swap04(int *,int *);
void testmalloc();
void testcalloc();
void testrealloc(int *);
void testvoid();
void test_type_rename();
void test_byte();
void test_pointer();
void test_pointer_func();
void test_pointer_string();
void test_struct();
void common_swap();
void hong();
void swap(void *,void *,int );
int main(int argc, const char * argv[])
{
test_byte();//测试每一种数据类型的字节数
test_type_rename();//测试数据类型重新命名类型名
test_pointer();//测试指针的用途
test_pointer_func();//指针函数和函数指针
test_pointer_string();//字符串数组和指针字符串
test_struct();
//四种交换算法(原数,地址,指针)
swap01(a, b);
swap02(&a, &b);
swap03(&p1, &p2);
swap04(p1, p2);
testmalloc();//malloc分配单块内存空间函数
testcalloc();///calloc连续分配内存空间函数
testrealloc(p2);//realloc重新定义内存分配空间的函数
common_swap();
hong();
return 0;
}
//可以被普遍使用的泛型swap
void swap(void *p1,void *p2,int size){
char *charat1 = (char *)p1;
char *charat2 = (char *)p2;
for(int i=0;i<size;i++){
int temp;
temp = *(charat1+i);
*(charat1+i) = *(charat2+i);
*(charat2+i) = temp;
}
}
//void型变量的通用特性
void testvoid(){
int *t1 = NULL;
int a = 1;
t1 = &a;
void *v1 = NULL;
v1 = t1;
long *t2 = NULL;
long b = 78687698679867;
t2 = &b;
void *v2 = NULL;
v2 = t2;
printf("v1 = %d\n",*(int *)v1);
printf("v2 = %ld\n",*(long *)v2);
}
malloc, calloc,realloc之间的区别
void realloc(void ptr, unsigned newsize);
void malloc(unsigned size);
void calloc(size_t nelem, size_t elsize);
都在stdlib.h函数库内
它们的返回值都是请求系统分配的地址,如果请求失败就返回NULL
malloc用于申请一段新的地址,参数size为需要内存空间的长度,如:
char p;
p=(char)malloc(20);
calloc与malloc相似,参数elsize 为申请地址的单位元素长度,nelem为元素个数,如:
char p;
p=(char)calloc(20, sizeof(char));
这个例子与上一个效果相同
realloc是给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度
如:
char p;
p=(char)malloc(sizeof(char)20);
p=(char)realloc(p,sizeof(char)*40);
注意,这里的空间长度都是以字节为单位。
C语言的标准内存分配函数:malloc,calloc,realloc等。
malloc与calloc的区别为1块与n块的区别:
malloc调用形式为(类型)malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。
calloc调用形式为(类型)calloc(n,size):在内存的动态存储区中分配n块长度为“size”字节的连续区域, 每一位都初始化为零,返回首地址。
realloc调用形式为(类型)realloc(ptr,size):将ptr内存大小增大到size。
free的调用形式为free(void*ptr):释放ptr所指向的一块内存空间。
C++中为new/delete函数。
//malloc分配单块内存空间函数
void testmalloc(){
//对p的单帧并没有清零,数值为随机数
int *p = malloc(sizeof(int));
if(p != NULL){
*p = 1234;
}else{
exit(1);
}
printf("*p = %d\n",*p);
free(p);
p = NULL;
}
//calloc连续分配内存空间函数
void testcalloc(){
//对p的每一帧都实现清零
int *p = calloc(5, sizeof(int));
if(p !=NULL){
for(int i=0;i<5;i++){
*(p+i) = i+2;
printf("*p = %d\n",*(p+i));
}
}else{
exit(1);
}
testrealloc(p);
p = NULL;
}
//realloc重新定义内存分配空间的函数
void testrealloc( int *p2){
int *re_p = realloc(p2, 10);
if(re_p !=NULL){
for(int i=5;i<10;i++){
*(re_p+i) = i+2;
}
for(int i=0;i<10;i++){
printf("*re_p = %d\n",*(re_p+i));
}
}else{
exit(1);
}
free(re_p);
re_p = NULL;
p2 = NULL;
}
void test_type_rename(){
long_byte_four a1 = 123;
printf("a1 == %d\n",a1);
}
int add(int a,int b){
return a+b;
}
int multiple(int (*func)(int,int),int n1,int n2){
return func(n1,n2)*n1;
}
//测试通用性交换算法
void common_swap(){
int a = 123;
int b = 456;
char ch1[] = "xiuyuliang";
char ch2[] = "wangruihah";
swap(&a,&b,sizeof(a));
printf("a = %d\n",a);
printf("b = %d\n",b);
swap(ch1, ch2, sizeof(ch1));
printf("ch1 = %s\n",ch1);
printf("ch2 = %s\n",ch2);
}
void swap01(int t1,int t2){
printf("最原始的纯数据交换(a,b)\n");
printf("a = %d\n",a);
printf("b = %d\n",b);
int temp;
temp = t1;
t1 = t2;
t2 = temp;
printf("a = %d\n",a);
printf("b = %d\n",b);
}
void swap02(int *t1,int *t2){
//swap02(&a, &b);
printf("仅仅交换副本指针的地址(&t1,&t2)\n");
printf("a = %d\n",a);
printf("b = %d\n",b);
int *temp = NULL;
temp = t1;
t1 = t2;
t2 = temp;
printf("a = %d\n",a);
printf("b = %d\n",b);
printf("t1 = %d\n",*t1);
printf("t2 = %d\n",*t2);
}
void swap03(int **t1,int **t2){
// swap03(&p1, &p2);
printf("真正交换了原始指针(p1,p2)\n");
printf("a = %d\n",a);
printf("b = %d\n",b);
int *temp = NULL;
temp = *t1;
*t1 = *t2;
*t2 = temp;
printf("a = %d\n",a);
printf("b = %d\n",b);
printf("t1 = %d\n",**t1);
printf("t2 = %d\n",**t2);
}
void swap04(int *t1,int *t2){
//swap04(p1, p2);
printf("真正交换了原值(a,b)\n");
printf("a = %d\n",a);
printf("b = %d\n",b);
int temp ;
temp = *t1;
*t1 = *t2;
*t2 = temp;
printf("a = %d\n",a);
printf("b = %d\n",b);
}
void test_byte(){
printf("char_byte === %ld\n" ,sizeof(char));
printf("int_byte === %ld\n" ,sizeof(int));
printf("long_byte === %ld\n" ,sizeof(long));
printf("short_byte === %ld\n" ,sizeof(short));
printf("double_byte === %ld\n" ,sizeof(double));
printf("long double_byte === %ld\n" ,sizeof(long double));
}
//测试指针的用途
void test_pointer(){
int a = 123;
int *b = &a;
int **c = &b;
printf("a = %d\n",a);//a的值
printf("&a = %p\n",&a);//a的地址
printf("b = %p\n",b);//b存的a的地址
printf("&b = %p\n",&b);//b的地址
printf("*b = %d\n",*b);//b存的地址解码为a的值
printf("c = %p\n",c);//c存的b的地址
printf("*c = %p\n",*c);//c存的b的地址解码为b的值,即a的地址
printf("**c = %d\n",**c);//c解码两次,第一次解码为b的值,即a的地址,第二次解码为a的值,为123
printf("&c = %p\n",&c);//c的地址
}
//指针函数和函数指针
//指针函数和函数指针的主要用途是作为参数传入函数或者方法
void test_pointer_func(){
int add(int ,int);
int (*pfunc)(int a,int b);
pfunc = add;
int result = pfunc(13,12);
printf("a+b == %d\n",result);
int multiple(int (*func)(int,int),int n1,int n2);
int result2 = multiple(add, 5, 3);
printf("(a+b)*a = %d\n", result2);
}
//字符串数组和指针字符串
void test_pointer_string(){
char ch1[] = "success";
char *ch2 = "success2";
char *ch3 = "success3";
char *ch2_copy = "success2";
printf("ch1 = %s\n",ch1);
printf("ch1的地址 = %p\n",ch1);
printf("ch2 = %s\n",ch2);
printf("ch2的地址 = %p\n",ch2);
printf("ch2_copy的地址 = %p\n",ch2_copy);
printf("ch3 = %s\n",ch3);
printf("ch3的地址 = %p\n",ch3);
}
//测试结构体输出
void test_struct(){
struct student *s1 = malloc(sizeof(struct student));
if(s1 !=NULL){
s1->age = 23;
s1->grade = 8;
s1->name = "xyl";
printf("s1.age = %d\n",s1->age);
printf("s1.grade = %d\n",s1->grade);
printf("s1.name = %s\n",s1->name);
}else{
exit(1);
}
free(s1);
s1 = NULL;
}
//检测宏定义的输出
void hong(){
int a[] = {1,23,45,9,23,89};
printf("array_size = %ld\n",SIZE_OF_ARRAY(a));
printf("%d\n",__LINE__);
printf("%s\n",__FILE__);
printf("%s\n",__TIME__);
printf("%s\n",__DATE__);
printf("%d\n",__STDC__);
xylINIT();
xylgirl();
}
小细节语法点
int x =123;
int a[] = {[7]=1,[0]=x+1,[4]=5};//针对性的设置数组中的特定数值,其余为0
char ch1[80] = "nihao woshi nidie";
char *ch2 = "nihao woshi nidei";
//这两个都可以运行顺利,但是意义不同,一个是表示一段内存区域的数值分配,另一个是引用一个指针指向一个字符数组
//空语句的功能
//功能是将键盘输入的字符存储到test指针指向的内存空间
while((*test = getchar()) != '')
;//空语句
//goto语句,实际上是一种执行跳转语句,直接跳转到goto后面标签标注的语句
//这是一种很不好的编程习惯,不利于他人对程序的理解
goto out_of_data;
...
...
...
out_of_data: NSLog(@"out of data");
int arraySum(int array[], int n)
int *arrayEnd = array+n;
//这里面虽然写的是arrgy[],但其实传入之后的array其实是一个地址,而且是数组的首地址
//一个例子说明这个问题
#import<Foundation/Foundation.h>
int arraySum(int array[], int n)
{
int *pr,*arrayEnd;
int sum = 0;
arrayEnd = array + n;
for(pr=array;pr<arrayEnd;pr++)
{
sum += *pr;
}
return sum;
}
int main(int argc, char const *argv[])
{
@autoreleasepool
{
int value[10] = {1,2,3,4,5,6,7,8,9,10};
NSLog(@"The sum is %i",arraySum(value,10));
return 0;
}
}
void NSLog(NSString *format,...);//...用途是声明参数有不定数目
块(BLOCK)
#import <Foundation/Foundation.h>
void (^calculateTriangleNumber)(int) =
^(int n)
{
int triangleNumber = 0;
for(int i=1;i<=n;i++)
{
triangleNumber += i;
}
NSLog(@"The triangleNumber of %i is %i",n,triangleNumber);
};//分号一定不要忘记,因为这是一个句子
int main(int argc,char *argv[])
{
@autoreleasepool
{
calculateTriangleNumber(10);
calculateTriangleNumber(20);
calculateTriangleNumber(50);
}
return 0;
}
结构体的相互借用
```
#import <Foundation/Foundation.h>
int main(int argc,char *argv[])
{
@autoreleasepool{
struct CGPoint
{
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
struct CGSize
{
CGFloat width;
CGFloat height;
};
typedef struct CGSize CGSize;
struct CGRect
{
CGPoint origin;
CGSize size;
};
typedef struct CGRect CGRect;
CGRect rect1 ;
CGPoint startp;
CGSize range;
startp.x = 100.0;
startp.y = 200.0;
range.width = 20.0;
range.height = 40.0;
rect1.origin = startp;
rect1.size = range;
NSLog(@"The rectangle :\n");
NSLog(@"width: %f",rect1.size.width);
NSLog(@"height: %f",rect1.size.height);
NSLog(@"origin: (%f,%f)",rect1.origin.x,rect1.origin.y);
}
return 0;
}
```
结构体声明变量的方法
//在结构体中声明多个变量
struct date
{
int year;
int month;
int day;
}today,tomorrow;
//直接在结构体中声明定义变量
struct date
{
int year;
int month;
int day;
}today = {2013,2,4};
struct today = {2014,1,21};
//直接的初始化方式
struct today = {.month = 2,.year = 1,.day = 21};
//可以打乱方式用.member = value赋值
//定义100天
struct
{
int year;
int month;
int day;
}date[100];