LinuxC应用开发学习笔记(二)--C语言
P30 数组数组:构造类型之一,连续存放int arr[M] = {1,2,3};printf("%d\n",sizeof(arr));printf("arr = %p\n",arr);//arr是个常量 不能无条件出现在等号左边。for(int i=0;i<M;i++){printf("%p-->%d\n",&arr[i],arr[i]);}int arr[] = {1,2,
P30 数组
数组:构造类型之一,连续存放
int arr[M] = {1,2,3};
printf("%d\n",sizeof(arr));
printf("arr = %p\n",arr); //arr是个常量 不能无条件出现在等号左边。
for(int i=0;i<M;i++)
{
printf("%p-->%d\n",&arr[i],arr[i]);
}
int arr[] = {1,2,3,4,5,6};
printf("%d\n",sizeof(arr)/sizeof(arr[0]));
数组:在内存当中是连续存放的内存空间,数组存储的类型是一致的。
一维数组
1、一维数组如何定义
[存储类型] 数据类型 标识符[下标]
2、初始化
不进行初始化、全部初始化、部分初始化(没初始化的都为0)、static(全部为0)
3、元素引用
数组名[下标]
4、数组名
数组名是表示地址的常量,也是整个数组的起始位置。
5、数组越界
数组越界不检查,是因为有指针偏移这个机制。a[i] = *(a+i);
1、斐波那契数列前十项 ,并且逆序存放
#include "stdio.h"
#include "stdlib.h"
#define M 3
#define N 10
static void fibonacci(void)
{
int i,j,temp;
int fib[10] ={1,1};
int arr[] = {1,2,3,4,5,6};
printf("%d\n",sizeof(arr)/sizeof(arr[0]));
for(int i = 2;i<=9;i++)
{
fib[i] = fib[i - 1] + fib[i - 2];
}
for(i=0;i<=9;i++){
printf("%d ",fib[i]);
}
printf("\n");
i = 0;
j = sizeof(fib)/sizeof(fib[0])-1;
while(i<j)
{
temp = fib[i];
fib[i] = fib[j];
fib[j] = temp;
i++;
j--;
}
for(i=0;i<=9;i++){
printf("%d ",fib[i]);
}
}
2、数据排序:冒泡,选择,快速排序
static void sort1(void)
{
int temp;
int a[N] = {12,8,45,30,98,67,2,7,68,11};
for(int i=0;i<=9;i++)
{
printf("%d ",a[i]);
}
printf("\n");
for(int i=0;i<N-1;i++)
{
for(int j = 0;j<N-1-i;j++)
{
if(a[j]>a[j+1])
{
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
for(int i=0;i<=9;i++)
{
printf("%d ",a[i]);
}
}
快速排序
static void sort2(void)
{
int i,j,k,temp;
int a[N] = {12,8,45,30,98,67,2,7,68,11};
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
printf("%d ",a[i]);
printf("\n");
for(i=0;i<=N-1;i++)
{
k = i;
for(j = i + 1 ;j<N;j++)
{
if(a[j]<a[k])
k = j;
}
if(i != k)
{
temp = a[i];
a[i] = a[k];
a[k] = temp;
}
}
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
printf("%d ",a[i]);
printf("\n");
}
3、进制转换
static void base_convert(void)
{
int i=0,num,base;
int n[128];
printf("please enter the convert num :");
scanf("%d",&num);
printf("please enter the base:");
scanf("%d",&base);
do
{
n[i] = num%base;
num = num/base;
i++;
}while(num != 0);
for(i--;i>=0;i--)
{
if(n[i]>=10)
printf("%c",n[i] - 10 +'A');
else
printf("%d",n[i]);
}
}
4、删除法求质数
static void primer(void)
{
char primer[1001] = {0};
for(int i=2;i<=1001;i++)
{
if(primer[i] == 0)
{
for(int j = i*2;j<=1001;j+=i)
{
primer[j] = -1;
}
}
}
for(int i=2;i<=1001;i++){
if(primer[i] == 0)
{
printf("%d ",i);
}
}
}
int main()
{
//fibonacci();
primer();
return 0;
}
二维数组
二维数组
1、定义、初始化
[存储类型] 数据类型 标识符 [行下标][列下标]
存储机制:按照行顺序存储。
只有行号可以省略,列号不可以省略。
arr是个常量 不能无条件出现在等号左边。
#include "stdio.h"
#include "stdlib.h"
#define M 2
#define N 3
int main()
{
int a[M][N] = {{1,2,3},{4,5,6}};
//int a[M][N] = {1,2,3,4,5,6};
int i, j;
printf("a = %p\n",a);
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)
{
printf("%p --> %d\n ",&a[i][j],a[i][j]);
}
printf("\n");
}
return 0;
}
2、元素引用
数组名[行标][列标]
3、存储形式
顺序存储、按行存储。
4、深入理解二维数组
多个一维数组组成的连续存储的空间。
a+1的跳转不是跳转一个整型 a相当于行指针,跳过了N个整型的距离。
int a[M][N] = {{1,2,3},{4,5,6}};
//int a[M][N] = {1,2,3,4,5,6};
int i, j;
printf("a = %p\n",a);
printf("a + 1 = %p\n",a+1);
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)
{
printf("%p --> %d\n ",&a[i][j],a[i][j]);
}
printf("\n");
}
return 0;
练习
1、行列互换
int i,j;
static void test(void)
{
int a[M][N] = {{1,2,3},{4,5,6}},b[N][M];
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)
{
printf("%d ",a[i][j]);
b[j][i] = a[i][j];
}
printf("\n");
}
for(i=0;i<N;i++)
{
for(j=0;j<M;j++)
{
printf("%d ",b[i][j]);
}
printf("\n");
}
}
2、求最大值及其所在位置
static void test2(void)
{
int a[M][N] = {32,4,23,89,9,7};
int i,j;
int max = a[0][0],row = 0,cloum = 0;
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)
{
if(max<a[i][j])
{
max=a[i][j];
row = i;
cloum = j;
}
}
}
printf("max : a[%d][%d] = %d\n",row,cloum,max);
}
3、求各行和各列的和
static void test3(void)
{
int a[5][4] = {{1,2,3},{4,5,6},{7,8,9},{10,11,12}};
for(int i=0;i<4;i++)
{
for(int j=0;j<3;j++)
{
a[4][3] +=a[i][j];
a[4][j] +=a[i][j];
a[i][3] +=a[i][j];
}
}
for(int i=0;i<5;i++)
{
for(int j=0;j<4;j++)
{
printf("%4d ",a[i][j]);
}
printf("\n");
}
}
4、矩阵乘积
static void test4(void)
{
int i,j,k;
int a[M][N] = {1,2,3,4,5,6};
int b[N][K] = {1,0,0,1,1,0};
int c[M][K] ;
for(i=0;i<M;i++)
{
for(j=0;j<K;i++)
{
for(k = 0;k<N;k++)
{
c[i][j] += a[i][k]*b[k][j];
}
}
}
for(i=0;i<M;i++)
{
for(j=0;j<K;j++)
printf("%4d",c[i][j]);
printf("\n");
}
}
p38
字符数组
1、定义,初始化,存储特点
[存储类型] 数据类型 标识符 [下标]
单个字符初始化、字符串常量初始化
static void test5(void)
{
char str[3] = {'a','b','c'};
//在存储的最后一位会有一个尾 \0
for(int i=0;i<N;i++)
{
printf("%c",str[i]);
}
printf("\n");
gets(str);//从标准输入中获取字符串,但是不检查数组越界现象,使用危险。
puts(str);
}
2、输入输出
static void test5(void)
{
char str[3] = {'a','b','c'};
//在存储的最后一位会有一个尾 \0
for(int i=0;i<N;i++)
{
printf("%c",str[i]);
}
printf("\n");
// gets(str);//从标准输入中获取字符串,但是不检查数组越界现象,使用危险。
// puts(str);
scanf("%s",str); //含有回车、空格、Tab无法获取。
printf("%s",str);
}
3、常用函数
strlen&sizeof
strcpy&stcncpy
strcat&strncat
strcmp&strncmp
static void test6(void)
{
#define STRSIZE 32
char str[STRSIZE] = "hello\0abc";
char str1[] = "hello";
printf("%d\n",strlen(str));//以尾0作为结束计算串的大小。
printf("%d\n",sizeof(str));//传参传进来真正所带的字节数。
strcpy(str,"abcde");
strncpy(str,"abcde",STRSIZE);
puts(str);
strcat(str1," ");
strcat(str1,"world");//把尾0去掉,然后补充新串补上尾0
strncat(str1,"abcde",STRSIZE);//最多从source中取N个字节,然后追加,没有N个的话,取到尾0为止 ,总的大小不会超过STRSIZE
puts(str1);
printf("%d\n",strcmp(str,str1));//比较结果是ASCII值,大的返回正,小的返回负,相等返回0
printf("%d\n",strncmp(str,str1,5));//比较前N个字符
//&strncmp
}
P40 练习题
1、计算输入的有多少个字符串。
static void test7(void)
{
char str[128];
int count = 0,flag = 0;
gets(str);
for(int i=0;str[i]!='\0';i++)
{
if(str[i] == ' ')
{
flag = 0;
}
else
if(flag == 0)
{
count++;
flag = 1;
}
}
printf("count = %d\n",count);
}
指针与变量
1、变量与地址的关系
变量名:用户对某一个内存空间的抽象表示。
指针就是地址,指向某一个地址值。
2、指针与指针变量
指针指向某一个地址值,指针变量:一个能够保存地址的变量,保存着指针。
static void test8(void)
{
int i = 1;
int *p = &i; //类型是int* ,指针存放的是变量的地址
int **q = &p;
printf("sizeof(i) = %d\n",sizeof(i));//整形所占大小
printf("sizeof(p) = %d\n",sizeof(p));//指针所占大小,
//不管什么类型的指针,在固定平台都占用固定字节大小
printf("i = %d\n",i);
printf("&i = %d\n",&i);//i的地址
printf("p = %d\n",p);//有他自己的地址,独立的空间
printf("&p = %d\n",&p);//指针p的地址
printf("*p = %d\n",*p);//访问i
printf("q = %d\n",q);//有他自己的地址,独立的空间
printf("*q = %d\n",*q);//存放指针p的地址
printf("**q = %d\n",**q);//访问i
}
3、直接访问&间接访问
直接访问:系统直接读取变量所在的地址的数据。
间接访问:系统通过调用c所在的地址,之后再读取地址存储的数据。
4、空指针&野指针
空指针:int *p = null;
野指针:没有确定指针的指向,指针定义出来就要赋值初值,没有初值就定义为空。
5、空类型的指针
void *q = NULL;//百搭数据类型
6、定义&初始化&书写规则
P44
7、指针运算
取地址&,取*,关系运算,++,–
static void test10(void)
{
int a[] = {5,1,7,2,8,3};
int y;
int *p = &a[1];
y = (*--p)++;
printf("y = %d\n",y);
printf("a[0] = %d\n",a[0]);
}
8、指针与数组
(1)指针与一维数组
static void test9(void)
{
int a[3] = {1,2,3};
int *p = a;
int i;
//p和a的区别就是,p是变量,a是常量。
// a[i]:a[i]=*(a+i) = *(p+i) = p[i];
// &a[i]:&a[i]=a+i = p+i= &p[i];
printf("%p,%p \n",a,a+1);
printf("%p,%p \n",p,p+1);
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
{
printf("%p -> %d \n",a+i,a[i]);
printf("%p -> %d \n",p+i,a[i]);
printf("%p -> %d \n",p+i,*(p+i));
printf("\n");
}
}
(2)指针与二维数组
static void test11(void)
{
int a[2][3] = {1,2,3,4,5,6};
int i,j;
int *p = *a;
int (*q) [3] = a;//指针数组
printf("%p %p ",a,a+1);
printf("%p %p ",q,q+1);
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("%p->%d ",*(a+i)+j,*(*(a+i)+j));
//printf("%p->%d ",&a[i][j],a[i][j]);
}
printf("\n");
}
}
P47
(3)指针与字符数组
static void test12(void)
{
char str[] = "i love china!";
char *p = str + 7;
puts(str);
puts(p);
}
static void test12(void)
{
char *str = "hello";
printf("%d %d\n",sizeof(str),strlen(str));
//strcpy(str,"world");//错误赋值方式,企图用world覆盖str串常量。
str = "world"; //指针,放弃指向hello的字符串,转向指向world的串。
puts(str);
// char str[] = "hello";
// printf("%d %d\n",sizeof(str),strlen(str));
// //str = "world";//错误,不能给常量赋值。
// strcpy(str,"world");//正确赋值方式,连续的存储空间。
// puts(str);
// char str[] = "i love china!";
// char *p = str + 7;
// puts(str);
// puts(p);
}
9、const与指针
static void test13(void)
{
/*
const int a;
int const a;
区分命名:1、看const开始念,const在前的是 常量指针,否则是指针常量。
2、 const int *p; 常量指针:指针指向可以发生变化,但是这块空间的数值是无法变化的。
int const *p;
int *const p; 指针常量:指针的指向永远不能变化,但是这块空间的数值是可以变化的。
const int *const p;
*/
#define PI 3.14 //宏最大的缺点不检查语法。
const float pi = 3.14; //需要当前的变量值一直保持不变,const使得变量常量化,优点是检查语法。
// const float *p = π//企图通过指针来给pi重新赋值。
// *p = 3.14159;
// printf("%f\n",pi);
//常量指针
// int i = 1;
// int j = 100;
// const int *p = &i;//指针指向可以发生变化,但是这块空间的值是无法变化的。
//T i = 10;
//F *p = 10;
//T p = &j;
//指针常量
// int i = 1;
// int j = 100;
// int *const p = &i;//指针指向可以发生变化,但是这块空间的值是无法变化的。
//T *p = 10; 对
//F p = &j; 企图给指针常量赋值,错
int i = 1;
int j = 100;
const int *const p = &i;
//F p = &i;
//F *p = 10;
printf("%d\n",*p);
}
P48
10、指针数组与数组指针
数组指针:指向数组的一个指针。数据类型 (*指针名)[下标]。
如: int (*p)[3]; -> type name ; --> int[3] *p;
p+1操作 一下子移动3个int类型。
static void test11(void)
{
int a[2][3] = {1,2,3,4,5,6};
int i,j;
int *p = *a;
int (*q) [3] = a;//指针数组
printf("%p %p ",a,a+1);
printf("%p %p ",q,q+1);
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("%p->%d ",*(a+i)+j,*(*(a+i)+j));
//printf("%p->%d ",&a[i][j],a[i][j]);
}
printf("\n");
}
}
指针数组:[存储类型] 数据类型 * 数组名[长度]
如:int *arr[3];-> TYPE NAME;–>int *[3] arr;
//数组指针:选择排序办法
static void test14(void)
{
int i,j,k;
char *name[5] = {"follow me","basic","great","fortran","computer"}; //指针数组
char *temp;
for(i=0;i<5-1;i++)
{
k = i;
for(j = i + 1; j < 5;j++)
{
if(strcmp(name[k],name[j])>0)
{
k = j;
}
}
if(k!=i)
{
temp = name[i];
name[i] = name[k];
name[k] = temp;
}
}
for(int i=0;i<5;i++)
{
puts(name[i]);
}
}
11、多级指针
以一级指针类推。
更多推荐
所有评论(0)