码迷,mamicode.com
首页 > 编程语言 > 详细

c语言---知识点总结2

时间:2015-05-01 07:08:22      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:

进制:

 %d\%i  十进制形式输出整数

 %c 输出字符

 %p 输出地址

 %f 输出小数

 %o 八进制形式输出整数

 %x 十六进制形式输出整数

 

内存存储:

字节 变量     内容

 ffc1

 

 ffc2 number2 0000 1101

 ffc3     0000 0000

 ffc4     0000 0000

 ffc5     0000 0000

 

 ffc6 number 0000 1100

 ffc7     0000 0000

 ffc8     0000 0000

 ffc9     0000 0000

 

 // 一个int类型数据占据4个字节、32bit

 // 0000 0000 0000 0000 0000 0000 0000 1100

    int  number=12;// 1100 

 // 0000 0000 0000 0000 0000 0000 0000 1101

    int number2 = 13; // 1101

技术分享

先存储number,后储存number2

 

1.二进制转十进制

 0b1100 = 0 * 2的0次方 + 0 * 2的1次方 + 1 * 2的2次方+ 1 * 2的3次方

        = 0 + 0 + 4 + 8 = 12

 0b1111 = 1 + 2 + 4 + 8 = 15

 0b1010 = 10

 

 2.十进制转二进制

 67 = 64 + 2 + 1 = 2的6次方 + 2的1次方 + 2的0次方

    = 0b1000000 + 0b10 + 0b1

  = 0b1000011

 

 3.n位二进制的取值范围

 2位二进制位的取值范围:0~3  0~2的2次方-1

 3位二进制位的取值范围:0~7  0~2的3次方-1

 n位二进制位的取值范围:0~2的n次方-1

 

 

 4个字节 -> 31bit

 0    000 0000 0000 0000 0000 0000 0000 1100

 0 ~ 2的31次方-1

 

类型说明符:

int 4个字节  %d

 short 2个字节 %d

 long 8个字节  %ld

 long long 8个字节 %lld

 

 signed

 unsigned  %u

 

signed和unsigned的区别:

      signed 最高位要当做符号位

     unsigned 最高位不要当做符号位

    signed == signed int

    signed 有符号:正数、0、负数

    unsigned int == unsigned

    unsigned 无符号:0、正数

 

位运算:

按位与 &

     10101010000

     00000100000

     -------------

     00000000000

     

     10111011

     10101101

     ---------

     10101001

     

     1001

     0101

     -----

     0001

     

     按位或 |

     1001

     0101

     -----

     1101

 

     按位异或 ^ 

     1.相同数值进行异或,结果肯定是0,比如9^9

     2.交换 9^5^6 == 9^6^5

     3.任何数值跟0进行异或,结果还是原来的数值,9^0 == 9

     4.a^b^a == a^a^b == 0^b == b

     

     1001

     0101

     -----

     1100

     

     1001

     1001

     -----

     00000

     

     0101

     0000

     ----

     0101

     

     9^5^9 == 9^9^5 = 0^5 = 5

     

     a^b^a == b

     

    //printf("%d\n", 9^9);

    

    //printf("%d\n", 9 ^ 5);

       

     按位取反 ~

     ~0000 0000 0000 0000 0000 0000 0000 1001

      1111 1111 1111 1111 1111 1111 1111 0110

     

    //printf("%d\n", ~9);

    

     左移 <<

     

     0000 0000 0000 0000 0000 0000 0000 0000

     00 0000 0000 0000 0000 0000 0000 100100

     

     9<<1 -> 9 * 2的1次方 == 18

     9<<2 -> 9 * 2的2次方 ==36

     9<<n -> 9 * 2的n次方

  

    //printf("%d\n", 9<<1);

      

     右移 >>

     0000 0000 0000 0000 0000 0000 0000 0000

     000000 0000 0000 0000 0000 0000 0000 10

     111111 1111 1111 1111 1111 1111 1111 10 

     

     8>>1 -> 8/2 == 4

     8>>2 -> 8/2的2次方 == 2

     8>>n -> 8/2的n次方

 

使用位异或运算符交换两个变量的值

借助第三方变量

    int temp = a;

    a = b;

    b = temp;

不使用第三方变量

    a = b - a;

    b = b - a;

    a = b + a;

使用位运算  位异或

// a^b^a == b

    a = a ^ b;

    b = a ^ b;

    a = a ^ b;

 

用位与&运算符判断变量的奇偶性

   15: 1111

     9:  1001

     

     14: 1110

     10: 1010

    a&1 == 1 // 奇数

    a&1 == 0 // 偶数

 

    if (a%2) {

        printf("奇数\n");

    } else {

        printf("偶数\n");

    }*/

    

    //a%2==0?printf("偶数\n"):printf("奇数\n");   

    //a%2?printf("奇数\n"):printf("偶数\n");

 

 

写一个函数,用来输出整数在内存中的二进制形式

void printBinary(int number)

{

    

    // 记录现在挪到第几位

    // (sizeof(number)*8) - 1 == 31

    int temp = ( sizeof(number)<<3 ) - 1;

    

    while ( temp >= 0 )

    {

        // 先挪位,再&1,取出对应位的值

        int value = (number>>temp) & 1;

        printf("%d", value);

        

        // 

        temp--;

        

        // 每输出4位,就输出一个空格

        if ( (temp + 1) % 4 == 0 )

        {

            printf(" ");

        }

    }

    

    printf("\n");

}

 

ASCII码表

     字符   ASCII码值

      A       65

      B       66

      C       67

      0       48

      a       97

 

 

char:

单引号‘‘只能扩住单字节的字符

char c = ‘男‘; // 错误写法

char c = "A";// 错误写法

char c = A; // 错误写法

char c = 65;(-128 ~ 127

 

1.说出下面程序的输出结构

 int i = 67 + ‘4‘;

 char c = ‘c‘ - 10;

 

 printf("%d - %c\n", i, i);

 printf("%d - %c\n", c, c);

 

 

2.写一个函数,将小写字母转为大写

char upper(char c)

{

    // 如果是小写字母,就转成大写

    /*

    if (c>=‘a‘ && c<=‘z‘) { // [‘a‘, ‘z‘]

        return c - (‘a‘-‘A‘);

    } else {// 如果不是小写字母,返回字母本身

        return c;

    }*/

    

    // 如果是小写字母,就转成大写

    if (c>=‘a‘ && c<=‘z‘) { // [‘a‘, ‘z‘]

        return c - (‘a‘-‘A‘);

    }

    // 如果不是小写字母,返回字母本身

    return c;

}

 

数组:

使用注意

    都是正确写法

    int ages[5] = {10 , 11, 12, 67, 56};

    int ages[5] = {10, 11};

    int ages[5] = {[3] = 10, [4] = 11};

    int ages[] = {10, 11, 14};

    

     错误写法

    int ages[];

    

     错误写法

     只能在定义数组的同时进行初始化

    int ages[5];

    ages = {10, 11, 12, 14};

    

    

    正确写法

    int ages[‘A‘-50] = {10, 11, 12, 14, 16};

    int size = sizeof(ages);

    printf("%d\n", size);

    

    正确写法

    int count = 5;

    int ages[count];

    ages[0] = 10;

    ages[1] = 11;

    ages[2] = 18;

   

    错误写法

    如果想再定义数组的同事进行初始化,数组元素个数必须是常量,或者不写

    int ages[count] = {10, 11, 12};

 

数组的定义格式: 类型 数组名[元素个数];

 

数组存储:

    char cs[5]= {‘a‘, ‘A‘, ‘D‘, ‘e‘, ‘f‘};

     printf("%p\n", cs);

     for (int i = 0; i<5; i++) {

     printf("cs[%d]的地址是:%p\n", i, &cs[i]);

     }

 

数组与函数:

数组作为函数参数,可以省略元素个数

数组作为函数参数,传递是整个数组的地址,修改函数形参数组元素的值,会影响到外面的实参数组

 

字符串:

char name[] = {‘i‘, ‘t‘, ‘c‘, ‘H‘, ‘s‘, ‘t‘, ‘\0‘};

char name[] = "itcast";

\0的ASCII码值是0

    char name[8] = "it";

    char name2[8] = {‘i‘, ‘t‘, ‘\0‘};

    char name3[8] = {‘i‘, ‘t‘, 0};

    char name4[8] = {‘i‘, ‘t‘};//这里隐蔽性隐藏了it字母后面有结束符,因为char name[8]表示{‘i‘,‘t‘,0,0,0,0,0,0}

 

    但是下面的不算是一个字符串(只能说是一个字符数组)

    char name5[] = {‘i‘, ‘t‘};//因为它没有结束符

 

"jack" == ‘j‘ + ‘a‘ + ‘c‘ + ‘k‘ + ‘\0‘    

    char name[10] = "jack888\n";

    // 把数组传入,仅仅是个警告

    printf(name);//因为printf函数里面只允许放置字符串常量

 

 

 \0的作用

 1.字符串结束的标记

 2.printf("%s", name2); 

 会从name2这个地址开始输出字符,直到遇到\0为止

 

strlen函数:计算字符串长度

 1.计算的是字符数,并不是字数。一个汉字算作3个字符

 2.计算的字符不包括\0

 3.从某个地址开始数字符的个数,直到遇到\0为止

 

编写一个函数char_contains(char str[],char c),

 如果字符串str中包含字符c则返回数值1,否则返回数值0

// 可读性 -> 性能 -> 精简(重构)

int char_contains(char str[], char c)

{

    int i = -1;

    

    /*

     i  3

     str[++i] ‘c‘

     c  ‘7‘

     */

    

    // 1.遍历整个字符串

    while ( str[++i] != c && str[i] != ‘\0‘ ) ;

    

    //return str[i] == ‘\0‘ ? 0 : 1;

    return str[i] != ‘\0‘;

}

/*

int char_contains(char str[], char c)

{

    int i = -1;

    

    // 1.遍历整个字符串

    while ( str[++i] )

    {

        // 如果发现某个字符等于参数c,直接返回1,退出函数

        if (str[i] == c)

        {

            return 1;

        }

    }

    

    // 2.说明str里面不包含字符c

    return 0;

}*/

 

/*

int char_contains(char str[], char c)

{

    int i = 0;

    

    // 1.遍历整个字符串

    while ( str[i] != ‘\0‘ )

    {

        // 如果发现某个字符等于参数c,直接返回1,退出函数

        if (str[i] == c)

        {

            return 1;

        }

        

        i++;

    }

    

    // 2.说明str里面不包含字符c

    return 0;

}*/

 

/*

int char_contains(char str[], char c)

{

    // 1.遍历整个字符串

    for (int i = 0; i<strlen(str); i++)

    {

        // 如果发现某个字符等于参数c,直接返回1,退出函数

        if ( str[i] == c )

        {

            return 1;

        }

    }

    

    // 2.说明str里面不包含字符c

    return 0;

}*/

 

 

char names[2][10]= {"jack", "rose"};

   printf("%s\n", names[0]);//jack

   printf("%c\n", names[0][3]);//k

    

    char names2[2][10] =

    {

        {‘j‘, ‘a‘, ‘c‘, ‘k‘, ‘\0‘},

        {‘r‘, ‘o‘, ‘s‘, ‘t‘, ‘\0‘}

    };

  //等同上述的char names[2][10]= {"jack", "rose"};

 

指针:

     变量类型  变量名;

     格式:变量类型 *变量名;

     定义了一个指针变量p

     指针变量只能存储地址

     指针就一个作用:能够根据一个地址值,访问对应的存储空间

     指针变量p前面的int:指针变量p只能指向int类型的数据

 注意:

    不建议的写法, int *p只能指向int类型的数据

    int *p;

    double d = 10.0;

    p = &d;

    

    指针变量只能存储地址

    int *p;

    p = 200;

    

   指针变量未经过初始化,不要拿来间接访问其他存储空间

    int *p;

    printf("%d\n", *p);

    

  定义变量时的*仅仅是一个象征,没有其他特殊含义

  *p = 20;//这个时候的*的作用:访问指向变量p指向的存储空间

 

p = 0;//清空指针

p = NULL;//清空指针

清空指针后,不能再间接访问其他存储空间

 

不能交换外面实参的值,仅仅是交换了内部指针的指向

void swap(int *v1, int *v2)

{

    int *temp;

    temp = v1;

    v1 = v2;

    v2 = temp;

}

 

交换的只是内部v1、v2的值

void swap(int v1, int v2)

{

    int temp = v1;

    v1 = v2;

    v2 = temp;

}

 

符号符:

 %d int

 %f float\double

 %ld long

 %lld long long

 %c char

 %s 字符串

 %zd  unsigned long

 

数组与指针:

1.数组元素的访问方式

 int ages[5];

 int *p;

 p = ages;

 1> 数组名[下标]  ages[i]

 2> 指针变量名[下标] p[i]

 3> *(p + i)

 

 2.指针变量+1,地址值究竟加多少,取决于指针的类型

  int *   4

  char *  1

  double * 8

 

  任何指针都占用8个字节的存储空间(对32位系统应该位4个字节,64系统为8个字节)

    char *cp;

    int *ap;

    long *bp;

 

指针变量p指向了数组的首元素

数组名就是数组的地址,也是数组首元素的地址

    //p = ages;

     p ---> &ages[0]

     p + 1 ---> &ages[1]

     p + 2 ---> &ages[2]

     p + i ---> &ages[i]

 

内存分配划分:

1.常量区

 存放一些常量字符串

 

 2.堆

 对象

 

 3.栈

 存放局部变量

 

 掌握:

 定义字符串的2种方式

 1> 利用数组

 char name[] = "itcast";

  * 特点:字符串里面的字符是可以修改的

  * 使用场合:字符串的内容需要经常修改

 

 2> 利用指针

  char *name = "itcast";

  * 特点:字符串其实是一个常量字符串,里面的字符是不能修改

  * 使用场合:字符串的内容不需要修改,而且这个字符串经常使用

 

(不包括\0)

 编写一个int string_len(char *s),返回字符串s的字符长度

int string_len(char *s)

{

    // 1.定义一个新的指针变量指向首字符

    char *p = s;

    

    /*

    while ( *s != ‘\0‘ )

    {

        s++;

    }*/

    

    while ( *s++ ) ; 

    

    return s - p - 1;

}

 

/*

int string_len(char *s)

{

    // 记录字符的个数

    int count = 0;

    

    // 如果指针当前指向的字符不是‘\0‘

    // 首先*s取出指向的字符

    // 然后s++

    while ( *s++ )

    {

        // 个数+1

        count++;

        

        // 让指针指向下一个字符

        //s = s + 1;

        //s++;

    }

    

    return count;

}

*/

 

/*

int string_len(char *s)

{

    // 记录字符的个数

    int count = 0;

    

    // 如果指针当前指向的字符不是‘\0‘

    while ( *s != ‘\0‘)

    {

        // 个数+1

        count++;

        

        // 让指针指向下一个字符

        //s = s + 1;

        s++;

    }

    

    return count;

}*/

 

编写一个函数,判断某个字符串是否为回文。

回文就是从左边开始读 和 从右边开始读 都是一样的,比如"abcba"

int isHuiwen(char *str)

{

    // 1.定义一个指向变量left指向字符串的首字符

    char *left = str;

    // 2.定义一个指向变量right指向字符串的末字符

    char *right = str + strlen(str) - 1;

    

    while (left < right)

    {

        // 如果左边和右边的字符不一样

        if (*left++ != *right--)

        {

            return 0;

        }

    }

    

    return 1;

}

 

编写一个函数void strlink(char s[], char t[])

 将字符串t连接到字符串s的尾部

用数组作形参:

void strlink(char s[], char t[])

{

    int i = 0;

    

    // 判断s[i]是否为字符串的尾部

    while ( s[i] != ‘\0‘ )

    {

        i++;

    }

    

    int j = 0;

    // 拷贝t的内容到s的后面

    while ( (s[i] = t[j]) != ‘\0‘ )

    {

        i++;

        j++;

    }

}

 

/*

 更加精简的写法,仅作为参考(会有警告信息)

void strlink2(char s[], char t[])

{

    int i = -1;

    

    // 判断s[i]是否为字符串的尾部

    while (s[++i]) ;

    

    int j = 0;

    // 拷贝t的内容到s的后面

    while (s[i++] = t[j++]) ;

}*/

用指针作形参:

void strlink(char *s, char *t)

{

    // 判断s[i]是否为字符串的尾部

    while ( *s != ‘\0‘ )

    {

        s++;

    }

    

    // 拷贝t的内容到s的后面

    while ( (*s = *t) != ‘\0‘ )

    {

        s++;

        t++;

    }

}

 

 

 

/*

 更加精简的写法,仅作为参考(会有警告信息)

 void strlink2(char *s, char *t)

 {

     // 判断s[i]是否为字符串的尾部

     while (*s++);

     

     // 减回一次

     s--;

     

     // 拷贝t的内容到s的后面

     while ( *s++ = *t++ ) ;

 }*/

 

指针总结:

一、指针变量的定义

1. 格式:变量类型 *指针变量名;

2. 举例:int *p;   char *p2;

3. 注意:定义变量时的*仅仅是指针变量的象征

 

二、利用指针变量简单修改其他变量的值

1.指向某个变量

int a;

 

int *p;

p = &a;

或者

int *p = &a;

 

2.修改所指向变量的值

*p = 10;

 

3.在函数内部修改外面变量的值

int a = 10;

change(&a);

 

void change(int *n)

{

    *n = 20;

}

 

三、指针与数组

1.将数组当做函数参数传入时,会自动转为指针

 

四、指针与字符串

1.定义字符串的2种方式

1> 利用数组

char name[] = "itcast";

* 特点:字符串里面的字符是可以修改的

* 使用场合:字符串的内容需要经常修改

 

2> 利用指针

char *name = "itcast";

* 特点:字符串其实是一个常量字符串,里面的字符是不能修改

* 使用场合:字符串的内容不需要修改,而且这个字符串经常使用

 

2.定义字符串数组

1> 利用二维字符数组

char names[2][10] = {"jack", "rose"};

 

2> 利用指针数组

char *names[2] = {"jack", "rose"};

 

c语言---知识点总结2

标签:

原文地址:http://www.cnblogs.com/cheng923181/p/4470281.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!