您的位置:首页 > 移动开发 > Objective-C

《objective-c程序设计》笔记——C语言相关篇

2014-10-30 23:29 225 查看


数组的使用

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];
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  objective-c c语言