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

4 C 语言 数值存储方式 数组

时间:2016-05-02 17:13:35      阅读:450      评论:0      收藏:0      [点我收藏+]

标签:源码 补码 反码 数组定义   初始化   使用   逆置   随机数 找最大数   冒泡排序   

源码 补码 反码

数组定义,初始化,使用,随机数

找最大数,逆置,冒泡排序,

scanf 输入字符串

字符串处理

字符串溢出等问题


scanf()

gets()

puts()

fputs()

strlen()

strcat()

strncat()

strcmp()

strncmp()

strchr()

strstr()

strtok()

atoi()

atof()

atol()



C 字符串数组


定义数组

遍历输出数组每个元素的值

//GCC 编译方式: C:\MinGW\project>gcc -std=c99 main.c
//编码环境 GBK
#include <stdio.h>
int main(){
int array[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
     //遍历二维数组,并打印
 for(int i=0;i< 3;i++){
for(int j=0;j<4;j++){
printf("array[%d][%d]=%d\n",i,j,array[i][j]);
}
}
/* 
输出 :
array[0][0]=0
array[0][1]=1
array[0][2]=2
array[0][3]=3
array[1][0]=4
array[1][1]=5
array[1][2]=6
array[1][3]=7
array[2][0]=8
array[2][1]=9
array[2][2]=10
array[2][3]=11 
*/
}



字符数组多种初始化方式

研究\0 对字符串数组的影响

#include <stdio.h>
int main(){
//字符串的初始化
//char str[100] ; //定义一个字符串
//char str[100] = {‘h‘,‘e‘,‘l‘,‘l‘,‘o‘}; //定义一个字符串,并初始化
char str[100] = "hello"; //多种初始化
     str[0] = ‘H‘;
     str[1] = ‘e‘;
     str[2] = ‘\0‘;       //遇到\0,字符串就结束了
     str[3] = ‘l‘;
     str[4] = ‘o‘;
 printf("%s\n",str); //字符串就是以\0结尾的数组
 //输出 He
 printf("str =%d\n",sizeof(str)); 
 //输出 str =100
}

看看字符串数组\0后面是什么东西

#include <stdio.h>
int main(){
 //固定字符数组大小,研究字符串初始化后是什么东西
 char str[10] = "Hello";
 printf("str =%d\n",sizeof(str)); 
 //输出 str2 =10
     printf("str[4]  char=>%c HEX=>%x\n",str[4],str[4]);
     printf("str[5]  char=>%c HEX=>%x\n",str[5],str[5]);
     printf("str[6]  char=>%c HEX=>%x\n",str[6],str[6]);
     printf("str[7]  char=>%c HEX=>%x\n",str[7],str[7]);
 //输出:
 // str[4]  char=>o HEX=>6f
 // str[5]  char=>  HEX=>0 
 // str[6]  char=>  HEX=>0
 // str[7]  char=>  HEX=>0
}






显示字符串长度大小

#include <stdio.h>
int main(){
 //打印字符数组大小
 char str1[] = "Hello";
 printf("str1 =%d\n",sizeof(str1)); 
 // 输出 str1 =6
}





修改字符串的内容

#include <stdio.h>
int main(){
 //修改字符串内容
 char str3[99]="Hello World!";
 printf("%s",str3);
 printf(str3);
 str3[4]=‘A‘;
 printf(str3);
 //输出 Hello World!Hello World!HellA World!
    
}


逆置数组

#include <stdio.h>
int main(){
char str3[99]="Hello World!";
int  low=0;
    int high=11; //注意上面的那个字符,11位之后就是\0了
    int tmp_var;
    while(low<high){
        tmp_var    =str3[low];
        str3[low]  =str3[high];
        str3[high]   =tmp_var;
        low++;
        high--;
 }
 printf(str3);
     //输出:
 //数组逆置:
     //!dlroW AlleH
}

显示GBK编码的汉字编码

//GBK  编码
#include <stdio.h>
int main(){
 char str4[100] ="你好 世界";
 printf("\n%s\n",str4);
 for(int i=0;i<13;i++){
 printf("%x\n",str4[i]);
 }
}
/*
C:\MinGW\project>gcc -std=c99 str.c
C:\MinGW\project>a.exe
你好 世界
ffffffc4
ffffffe3
ffffffba
ffffffc3
20
ffffffca
ffffffc0
ffffffbd
ffffffe7
0
0
0
0
*/


显示GBK编码的汉字

//GBK  编码
#include <stdio.h>
int main(){
 //用GBK编码显示 汉字
char str5[100];
    str5[0]=0xc4;
    str5[1]=0xe3;
    str5[2]=0;
    printf(str5);
    //输出 你
}



scanf函数漏洞演示:

遇到空格一定会对scanf有影响

#include <stdio.h>
int main(){
    char a[3]={0};
    char b[3]={0};
    scanf("%s",a);
    scanf("%s",b);
printf("==========\n");
printf("%s\n",a);
printf("%s\n",b);
}
测试:
C:\MinGW\project>gcc -std=c99 str.c
正常输入:
C:\MinGW\project>a.exe
12
qw
==========
12
qw




溢出测试1

C:\MinGW\project>a.exe
12
qwqwqwwqwqw
==========
wqwwqwqw
qwqwqwwqwqw
溢出测试2
C:\MinGW\project>a.exe
123 qwerty
==========
rty
qwerty


scanf 溢出的原因:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
    char a[10]={0};
    char b[300]={0};
int  c[10];
    printf("a address %p\n",a);
    printf("b address %p\n",b);
    printf("c address %p\n",c);
system("pause"); //程序等待在这里
}
/*
C:\MinGW\project>gcc str.c
C:\MinGW\project>a.exe
a address 0028FF16
b address 0028FDEA
c address 0028FDC0
请按任意键继续. . .
*/

scanf会把接受到的值,在内存从开始存,不会去管是否已经溢出

这样会导致覆盖其他变量的数值






可以看出,程序已经出错

gets可以解决scanf的无法记录空格的问题
#include <stdio.h>
int main(){
    char a[30]={0};
    gets(a);
printf(a);
}
C:\MinGW\project>a.exe
hello world !
hello world !


但是依然会缓冲区溢出

#include <stdio.h>
int main(){
    char a[3]={0};
    char b[3]={0};
    gets(a);
    gets(b);
printf("%s\n",a);
printf("%s\n",b);
}
C:\MinGW\project>a.exe
123456789
qwertyuioop
rtyuioop
qwertyuioop
C:\MinGW\project>


fgets解决了空格 缓存区溢出问题

#include <stdio.h>
int main(){
    char a[5]={0};
   // fgets(a,5,stdin);
    fgets(a,sizeof(a),stdin);
printf("%s\n",a);
}
C:\MinGW\project>gcc -std=c99 str.c
C:\MinGW\project>a.exe
12 e343 423
12 e



puts会在输出后面加入一个\n

#include <stdio.h>
int main(){
    char a[]="Hello world !";
puts(a);
printf("==================");
printf(a);
printf("==================");
}
C:\MinGW\project>gcc -std=c99 str.c
C:\MinGW\project>a.exe
Hello world !
==================Hello world !==================

fput函数,可以代替printf

#include <stdio.h>
int main(){
    char a[]="Hello world !";
fputs(a,stdout);
}
C:\MinGW\project>gcc -std=c99 str.c
C:\MinGW\project>a.exe
Hello world !


对输入的字符,逆置

#include <stdio.h>
int main(){
    char a[99]={0};
scanf("%s",a);
printf("%s \n",a);
//strlen  返回是数组有效长度,不包含\0
//获取字符串真实长度,相当于strlen
int i = 0;
while(a[i] != ‘\0‘) i++;
//逆置字符数组
int low = 0;
int high= i-1; //因为字符数组有一个‘\0‘
char tmp;
while(low < high){
tmp    = a[low];
a[low] = a[high];
a[high]= tmp;
low++;
high--;
}
printf("%s \n",a);
}
C:\MinGW\project>gcc -std=c99 str.c
C:\MinGW\project>a.exe
qwertyuio09876
qwertyuio09876
67890oiuytrewq
C:\MinGW\project>a.exe
你好
你好
strlen 4
sizeof 99
煤隳




字符串追加:

注意:可能导致溢出

#include <stdio.h>
#include <string.h>
int main(){
    char a[99]={0};
    char b[300]={0};
    scanf("%s",a);
    scanf("%s",b);
strcat(a,b); //把b追加到a后面,a要足够大
printf("a+b=%s\n",a);
}
C:\MinGW\project>a.exe
123
abc
a+b=123abc



手动实现strcat

#include <stdio.h>
#include <string.h>
int main(){
    char a[99]={0};
    char b[300]={0};
    scanf("%s",a);
    scanf("%s",b);
//strcat(a,b); //把b追加到a后面,a要足够大
//手写一个strcat
int lena = strlen(a);
int lenb = strlen(b);
for(int i = lena;i < lena + lenb;i++){
a[i] = b[i-lenb];
}
printf("a+b=%s\n",a);
}
C:\MinGW\project>gcc -std=c99 str.c
C:\MinGW\project>a.exe
123
abc
a+b=123abc



strncat指定追加个数

#include <stdio.h>
#include <string.h>
int main(){
    char a[10]={0};
    char b[300]={0};
    scanf("%s",a);
    scanf("%s",b);
    strncat(a,b,sizeof(a)-strlen(b)-1); //留一个‘\0‘
printf("a+b=%s\n",a);
}
/*
C:\MinGW\project>gcc -std=c99 str.c
C:\MinGW\project>a.exe
12345
qwertyuiop
a+b=12345qwertyuiop
*/











1         整数在计算机内部的存储方式

1.1      原码

将最高位做为符号位(0代表正,1代表负),其余各位代表数值本身的绝对值

+7的原码是00000111

-7的原码是10000111

+0的原码是00000000

-0的原码是10000000

 

 

1.2      反码

一个数如果值为正,那么反码和原码相同

一个数如果为负,那么符号位为1,其他各位与原码相反

+7的反码00000111

-7的反码11111000

-0的反码11111111

 

1.3      补码

原码和反码都不利于计算机的运算,如:原码表示的7-7相加,还需要判断符号位。

正数:原码,反码补码都相同

负数:最高位为1,其余各位原码取反,最后对整个数 + 1

-7的补码:=

 10000111(原码)

111111000(反码)

11111001(补码)

+0的补码为00000000

-0的补码也是00000000

补码符号位不动,其他位求反,最后整个数+ 1,得到原码

用补码进行运算,减法可以通过加法实现

7-6=1

7的补码和-6的补码相加:00000111 + 11111010 = 100000001

进位舍弃后,剩下的00000001就是1的补码

-7+6 = -1

-7的补码和6的补码相加:11111001 + 00000110 = 11111111

11111111-1的补码

 

2         数组

内存连续,并且是同一种数据类型的变量,C语言的数组小标好是从0开始的,到n-1.

2.1      一维数组定义与使用

类型变量名称[数组元素的个数];

2.2      数组在内存的存储方式

在内存当中是连续的内存空间地址。

2.3      一维数组初始化

int array[10] = {0};//将数组所有元素都初始化为0

int array[10] = {0,1,2,3,4,5,6,7,8,9}

数组中找最大值思路

 技术分享

数组中找第二大值思路

 

技术分享


 

 

逆置数组思路

 技术分享

 

测量楼宇高度的说明

 技术分享

测量地球太阳距离的说明

 技术分享

测量太阳木星距离的说明

 技术分享

2.4      二维数组定义与使用

intarray[3][4];//12个元素的二维数组

2.5      二维数组初始化

 

int a[3][4]  = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };

 

3         字符串与字符数组

3.1      字符数组定义

char buf[100];

对于C语言字符串其实就是一个最后一个元素为’\0’char数组.

3.2      字符数组初始化

char buf[] = “hello world”;

3.3      字符数组使用

 

3.4      随机数产生函数randsrand

头文件stdlib.h

   #include<time.h>

int t = (int)time(NULL);

   srand(t);

   for (int i = 0; i  < 10; i++)

   {

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

   }


 

 

3.5      scanf输入字符串

char buf[100] = {0};

scanf(“%s”, buf);

scanf("请输入i的值%d",&i);

3.6      字符串的结束标志

 

3.7      字符串处理函数

3.7.1         gets

gets没有解决缓冲区溢出的问题.

3.7.2         fgets函数

gets函数不检查预留缓冲区是否能够容纳用户实际输入的数据。多出来的字符会导致内存溢出,fgets函数改进了这个问题。

由于fgets函数是为读取文件设计的,所以读取键盘时没有gets那么方便

    char s[100] = { 0 };

    fgets(s, sizeof(s), stdin);

 

3.7.3         puts函数

puts函数打印字符串,与printf不同,puts会在最后自动添加一个’\n’

    char s[] =  "hello world";

    puts(s);

 

3.7.4         fputs函数

fputs是puts的文件操作版本,

    char s[] =  "hello world";

    fputs(s, stdout);

3.7.5         strlen,字符串长度

strlen返回字符串的长度,但是不包含字符串结尾的’\0’

char buf[10]

sizeof(buf);//返回的是数组buf一共占据了多少字节的内存空间.

3.7.6         strcat,字符串追加

char str1[100];

char str2[100];

strcat(str1, str2);//str2追加到str1的后面

str1一定要有足够的空间来放str2,不然会内存溢出.

3.7.7         strncat,字符串有限追加

strncat(str1, str2, sizeof(str1) –strlen(str1) - 1);

 

3.7.8         strcmp,字符串比较

strcmp(a, “str”);//如果两个参数所指的字符串内容相同,函数返回0

3.7.9         strncmp,字符串有限比较

strncmp(str, “exit”, 4);

3.7.10      strcpy字符串拷贝

strcpy(str, “hello world”);//存在溢出的问题,

3.7.11      strncpy字符串有限拷贝

strcpy(str, “hello world”, 7);

3.7.12      sprintf,格式化字符串

printf是向屏幕输出一个字符串

sprintf是向char数组输出一个字符串,其他行为和printf一模一样

sprintf也存在缓冲区溢出的问题

3.7.13      strchr查找字符

strchr(str, ‘c’);

返回值是字符’c’在字符串str中的位置

3.7.14      strstr查找子串

3.7.15      strtok分割字符串

字符在第一次调用时strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL每次调用成功则返回指向被分割出片段的指针

   char buf[]  = "abc@defg@igk";

   char *p =  strtok(buf, "@");;

   while (p)

   {

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

      p = strtok(NULL, "@");

   }

 

3.7.16      atoi转化为int

 

3.7.17      atof转化为float

 

3.7.18      atol转化为long

 

 

技术分享


 

作业说明:

不可以用任何已有的函数,完全自己写代码,完成十进制字符串转化为十进制的整数

作业思路:

 技术分享


本文出自 “魂斗罗” 博客,请务必保留此出处http://990487026.blog.51cto.com/10133282/1769432

4 C 语言 数值存储方式 数组

标签:源码 补码 反码 数组定义   初始化   使用   逆置   随机数 找最大数   冒泡排序   

原文地址:http://990487026.blog.51cto.com/10133282/1769432

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