/*************************************************************************
> File Name: class.c
> Author: khalil
> Mail: [email protected]
> Created Time: Sat 31 Oct 2015 09:29:49 AM CST
************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//七月算法视频课
//《编程之法》July
// ***nginx
// 深入理解nginx 模块开发与架构解析(jb51.net)
//
#if 1
// a = b ;
// 左值: 空间(变量、内存中的值)
// 右值: 值;
// (++b)--;
// (a++)++;
// 他们都是错的:表达式不能作为左值!;
// ++b是得到的一个常量 不能进行运算。
//
// int a = 10;
// int b = 20;
//(1) b = ++a + b;
// b = 11 + 20 = 31;
//(2) b = a++ + b;
// b = 10 + 20 = 30 , a = 11;
//为什么使用前置++?:
// 前置++ 在C++中多一步操作 所以使用++
#endif
#if 0
int max(int a , int b);
int max2(int a , int b , int c);
int max(int a , int b)
{
return a > b ? a:b;
}
int max2(int a , int b , int c)
{
// return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c );
// 三目运算符是不推荐的,容易写错
return max(max(a,b),c);
}
int main ( int argc , char **argv )
{
int a = 10 ;
int b = 20 ;
int c = 30 ;
int max_value = 0;
max_value = max2( a, b, c);
printf("%d\n",max_value);
if ( 1 < a < 20 );
// 如果1<a return 1 然后再 1<20 和想象中的并不一样
if ( 1 < a && a < 20 );
// 这才是可用的形式
return 0 ;
}
#endif
#if 0
//组件化思想
char *my_strcpy(char *des , const char *src);
char *my_strcpy(char *des , const char *src)
{ //使用memcpy进行拷贝
return (char *)memcpy(des,src,strlen(src)); //把src内容拷到des
}
int main ( int argc , char** argv )
{
char *str1 = "hello,world!";
char str2[20] = {0};
my_strcpy(str2,str1);
printf("str2:%s\n",str2);
return 0;
}
#endif
#if 0
int main(int argc , char **argv)
{
// && || 的短路运算:提前预知真假
//
int a = 10 ;
int b = 20 ;
int c ;
if ( a > 20 && b > 10 );
// 只要条件1 不满足 立即退出判断 b>20 被短路,不用判断
if ( a > 5 || b < 6 );
// 只要条件1 满足 立即退出判断 b<6 被短路,不用判断
c = (10 , 20); //不能用int c = 10 ,20 ;
printf("%d\n",c); // c = 20
return 0 ;
}
#endif
#if 0
int main ( int argc , char ** argv)
{
int array[]= {5,123,213,23,56,89,35};
printf("%d\n",array[2]);
printf("%d\n",2[array]); // 一样的
printf("%c\n",2["hi!"]);
// [] == + []被当作操作数处理
//
// a [b] ==> b[a]
//
// a + b = b + a
}
#endif
#if 0
//自定义布尔值
#define false (0)
#define true (1)
typedef unsigned char Bool;
int main ( int argc , char **argv )
{
Bool ok = false;
if (ok == false){
printf("False!\n");
}else{
printf("True!\n");
}
}
#endif
#if 0
int main (int argc , char ** argv)
{//隐式类型转换
char a = 10;
int b = 20;
b = a + b ; //a (char) --> a (int)
//1.数值范围小的转化为大的
//2.整形:有符号的转换为无符号的
//3.整形和浮点类型: 都转化为double类型
//
int *p[20]; //一个指针数组 有20个指针
int (*q)[20]; //一个指向20个单位的int数组的指针
}
#endif
#if 0
void my_bzero(void *src, size_t n);
void my_bzero(void *src, size_t n)
{
memset(src, 0, n);
}
int main (int argc, char **argv)
{
int a = 10;
int array[10] = {1,2,3}; //不完全赋值
char str[20] = {0};
int *p = &a; //定义一个指针记录a的地址
memset( str, 0, sizeof(str));
bzero(str, sizeof(str));
// 0 - 9 , 数组下标不要越界,预防差1多1错误
array[5] = 10;
array; //数组名是一个常量,记录了数组首地址
// array = p;//不可被修改!
p = array;
//是否相同?
p[1] = 15;
array[1] = 15;
int (*q)[10] = &array; // <- 指向数组的指针
// 其实int数组的类型是 int[数组长度] 所以不能int **q = &array
*((int*)(q + 1) - 1) = 20;
// 指向下一个数组再往前指一位到数组的末尾
printf("%d\n",array[9]);
return 0 ;
}
#endif
#if 0
int sum (int array[],int len);
int sum (int array[],int len)
{ //当参数时一个数组的时候,其实只传递了指针
//也就是说,编译器为了提高效率,把数组转换为了指针
//
int i = 0;
int result = 0;
for ( i = 0; i < len; ++i)
{
result += array[i];
}
return result;
}
int main(int argc, char **argv)
{
int array[] = {12,213,42,65,78}; //定义时数组和指针时不同的
int *p = array;
//外部声明时,指针和数组不同
int result = 0;
// 指针和数组的相同与不同
//
// 1.在函数的参数传递中,指针和数组都被看作是指针,这是为了提升
// 程序运行的效率
// 2.在表达式中,我们认为:a[i] = *(a + i) 数组效率会高一些
// 3.在定义的时候不同,数组名字不能被指针赋值,它是常量
// 4.extern:
// test1.c: int array[100] //定义式
// test2.c: extern int *array //外部声明
// array[2] = 10 ; //会直接报错
//
//
result = sum(array,sizeof(array)/sizeof(int));
return 0 ;
}
#endif
#if 0
int main(int argc, char **argv)
{
char *str1 = NULL;
char *str2 = NULL;
#if 0
// 多人共用一块空间: 《浅拷贝》
str1 = (char *)malloc(20);
strcpy(str1,"hello,world!");
str2 = str1;
free(str1);
#endif
#if 1
// 《深拷贝》:
str1 = (char *)malloc(20);
strcpy(str1,"hello,world!");
str2 = (char *)malloc(strlen(str1) + 1); //用strlen统计长度记得+1
strcpy(str2, str1);
free(str1);
#endif
printf("str2: %s\n",str2);
return 0;
}
#endif
#if 0
int main (int argc , char** argv)
{
int array[3][4] = {0};
int (*p)[4] = array; // int[4] *p
p += 1;
printf("%x\n",array);
printf("%x\n",p);
//
// 内存是线性的
//
*((int *)p - 1) = 20;
printf("a[0][3] = %d\n",array[0][3]);
return 0;
}
#endif
#if 0
int main(int argc ,char **argv)
{
int i = 0;
for (i = 0; i < argc; ++i)
{
printf("argv[%d]: %s\n",i,argv[i]);
}
return 0;
}
#endif
#if 0
int main(int argc, char **argv)
{
int i = 0;
int j = 0;
int tmp = 0;
int *p_int = NULL;
if (argc < 2)
{
fprintf(stderr,"Invalid arguments!\nUsage:./sort num1 num2 num3...\n");
exit(1);
}
p_int = (int*)malloc(sizeof(int)*(argc - 1));
if(p_int == NULL){
fprintf(stderr,"Memory full!\n");
exit(1);
}
for (i = 0; i < (argc - 1) ; ++i)
{
p_int[i] = atoi(argv[i+1]);
}
for (i = 0; i < argc - 1; ++i)
{
for(j = i; j < argc - 1; ++j)
{
if(p_int[j] > p_int[j+1])
{
tmp = p_int[j];
p_int[j] = p_int[j+1];
p_int[j+1] = tmp;
}
}
}
for (i = 0; i < argc - 1; ++i)
{
printf("no.%d : %d\n",i,p_int[i]);
}
return 0;
}
#endif
#if 0
//扩展字符串
char *extend_str(const char *dest_str,const char *src_str,int length)
{
if (dest_str == NULL || src_str == NULL)
{
fprintf(stderr,"InputErr!\n");
exit(1);
}
char *dest = (char *)dest_str;
char *src = (char *)src_str;
char *result = (char *)dest_str;
int i = 0;
int j = 0;
for(i = 0; src[i] != '\0'; ++i)
{
if(src[i] == '-'){
if(src[i-1] < src[i+1])
{
for(j = 1; j < (src[i+1] - src[i-1]); ++j)
{
*dest++ = src[i-1] + j;
}
}else{
}
}else{
*dest++ = src[i];
}
}
return result;
}
int main(int argc, char **argv)
{
char *str1 = "hello,a-c,a-z,world!\n";
char *str2 = (char*)malloc(sizeof(char)*128);
printf("before: %s\n",str1);
extend_str(str2,str1,strlen(str1));
printf("after: %s\n",str2);
}
#endif
#if 0
char *delete_str(const char *dest_str,const char *src_str,int length,int len_des);
char *delete_str(const char *dest_str,const char *src_str,int length,int len_des)
{
char *dest = (char*)dest_str;
char *src = (char*)src_str;
int i = 0;
int j = 0;
int k = 0;
int flag = 0;
for(i = 0; i < length; ++i)
{
if(src[i] == dest[0]){
for(j = 1; dest[j] != '\0'; ++j)
{ //printf("%c\n",dest[j]);
if(src[i+j] != dest[j]){
break;
}
}
if(dest[j] == '\0'){
for(k = i; src[k] != '\0'; ++k)
{
src[k] = src[k+len_des-1];
}
i += len_des;
}
}else{
}
}
}
int main(int argc, char **argv)
{
char str1[] = "hello,everyoneworld!";
char str2[] = "everyone";
printf("defore: %s\n",str1);
delete_str(str2,str1,sizeof(str1)/sizeof(char),sizeof(str2)/sizeof(char));
printf("after: %s\n",str1);
return 0;
}
#endif
#if 0
//函数指针
typedef void (*Move)(void); //指向形如 void func(void) 的函数
//结构体
struct People{
//属性
char name[100];
short age;
char id[20];
//操作
Move move;
};
typedef struct A{
int a;
char b;
}A;
typedef struct List_node{
int data; //数据域
struct List_node *next; //指针域
A a;
}List_node;
int main (int argc, char **argv)
{
//struct
struct People people1;
List_node node1 = { //显式声明
.data = 10,
.next = NULL
};
List_node node2 = {0};
List_node *p = &node1;
node1.next = &node2;
(*p).data = 30;
p->data = 40; //原来的(*p)->data舍弃不用,换为这种形式
node1.a.b = 20; //结构体套结构体
printf("%d\n",node1.data);
return 0;
}
#endif
#if 0
typedef struct A{
char a; //1
short b; //2
int c; //4
//a_bb cccc
}A;
typedef struct B{
int a; //4
char b; //5
short c; //8
char d; //9
double e; //24
char f; //32
}B;
//数据成员会以自己的开头与自身的数据长度对齐
//同时结构体还会自动总体对齐于最大数据成员的长度
typedef struct C{
char a;
short b;
struct D
{
char d;
double e;
} g; //如果没有g那么D不占空间
//对齐还是依据成员变量的空间
//而不是结构体中结构体的空间对齐
int c;
int f;
}C;
typedef struct W{
char a;//1
double b;//16
short c;//18
union R{
int a;
double b;
} d; //32
double e;//40
int f;//48
}W;
int main(int argc, char **argv)
{
A a;
A *p = NULL;
printf("size of (A):%d\n",sizeof(a));
printf("size of (B):%d\n",sizeof(B));
printf("size of (C):%d\n",sizeof(C));
printf("size of (W):%d\n",sizeof(W));
p = &a;
//引用由于内存对齐而损失的一小块内存
*((char*)p + 1 ) = '1';
printf("%p\n",&a.a);
printf("%p\n",&a.b);
printf("%p\n",&a.c);
return 0;
}
#endif
#if 0
union A{
int value; // 0x0000 0001
char c[4]; // c[0] c[1] c[2] c[3]
};
// 0x12345678
//
// 大端机器存的位置相反(高位在低位)
void judge_machine_type(void)
{
union A a = {1};
if(a.value == a.c[0]){
printf("This machine is small machine!\n");
}else{
printf("This machine is big machine!\n");
}
}
int main (int argc, char **argv)
{
judge_machine_type();
return 0;
}
#endif
#if 0
//函数
//函数必备:
//
// 1.函数名
// 2.参数列表
// 3.返回值
// 规则:
// 1.函数先声明再定义
// 2.函数调用时,实参和型参在数量、顺序、类型上要保持一致
//
int min(int a, int b);
int min(int a, int b)
{
return a > b ? b : a;
}
int main(int argc, char **argv)
{
return 0;
}
#endif
#if 1
//void print_int_array(int *array, int length);
//
//void print_int_array(int *array, int length)
//{
// int i = 0;
// if (array!= NULL && length > 0){
// for( i = 0; i < length; ++i ){
// printf("%d ",array[i]);
// }
// printf("\n");
// }
//}
typedef void (*Print_func)(void *, int);
static void print_int(void *array, int index);
static void print_float(void *array, int index);
static void print_int(void *array, int index)
{
printf("%d ",*((int *)array + index));
}
static void print_float(void *array, int index)
{
printf("%f ",*((float *)array + index));
}
void foreach(void *array, int length, Print_func print);
void foreach(void *array, int length, Print_func print)
{
int i = 0;
for(i = 0; i < length; ++i){
print(array,i);
}
printf("\n");
}
int main (int argc, char **argv)
{
int array[] = {12,123,4,5,67,8,90};
int length = sizeof(array) / sizeof(int) ;
float array1[] = {12.4,1.3,4.6,0.123};
int length1 = sizeof(array1) / sizeof(float);
foreach(array, length, print_int);
foreach(array1, length1, print_float);
return 0;
}
#endif
【2015/11/1】C学习日志_Day11&12 数据类型 指针 内存对齐 函数指针
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hsgwpj/article/details/49561613
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.